js综合笔记

if else

var s = '123';
if (s.length) { // 条件计算结果为3
    //
}

  JavaScript把nullundefined0NaN和空字符串''视为false,其他值一概视为true,因此上述代码条件判断的结果是true

iterable

遍历Array可以采用下标循环,遍历MapSet就无法使用下标。为了统一集合类型,ES6标准引入了新的iterable类型,ArrayMapSet都属于iterable类型。

具有iterable类型的集合可以通过新的for ... of循环来遍历。

for ... of循环遍历集合,用法如下:

var a = ['A', 'B', 'C'];
var s = new Set(['A', 'B', 'C']);
var m = new Map([[1, 'x'], [2, 'y'], [3, 'z']]);
for (var x of a) { // 遍历Array
    console.log(x);
}
for (var x of s) { // 遍历Set
    console.log(x);
}
for (var x of m) { // 遍历Map
    console.log(x[0] + '=' + x[1]);
}

你可能会有疑问,for ... of循环和for ... in循环有何区别?

for ... in循环由于历史遗留问题,它遍历的实际上是对象的属性名称。一个Array数组实际上也是一个对象,它的每个元素的索引被视为一个属性。

当我们手动给Array对象添加了额外的属性后,for ... in循环将带来意想不到的意外效果:

var a = ['A', 'B', 'C'];
a.name = 'Hello';
for (var x in a) {
    console.log(x); // '0', '1', '2', 'name'
}

for ... in循环将把name包括在内,但Arraylength属性却不包括在内。

for ... of循环则完全修复了这些问题,它只循环集合本身的元素:

var a = ['A', 'B', 'C'];
a.name = 'Hello';
for (var x of a) {
    console.log(x); // 'A', 'B', 'C'
}

这就是为什么要引入新的for ... of循环。

然而,更好的方式是直接使用iterable内置的forEach方法,它接收一个函数,每次迭代就自动回调该函数。以Array为例:

'use strict';
var a = ['A', 'B', 'C'];
a.forEach(
function (element, index, array) { // element: 指向当前元素的值 // index: 指向当前索引 // array: 指向Array对象本身 console.log(array+'中'+element + ', index = ' + index); });

SetArray类似,但Set没有索引,因此回调函数的前两个参数都是元素本身:

var s = new Set(['A', 'B', 'C']);
s.forEach(function (element, sameElement, set) {
    console.log(element);
});

Map的回调函数参数依次为valuekeymap本身:

var m = new Map([[1, 'x'], [2, 'y'], [3, 'z']]);
m.forEach(function (value, key, map) {
    console.log(value);
});

如果对某些参数不感兴趣,由于JavaScript的函数调用不要求参数必须一致,因此可以忽略它们。例如,只需要获得Arrayelement

var a = ['A', 'B', 'C'];
a.forEach(function (element) {
    console.log(element);
});

 

  Web 计时

  Web 计时机制的核心是 window.performance 对象。对页面的所有度量信息,包括那些规范中已经定义的和将来才能确定的,都包含在这个对象里面。Web Timing 规范一开始就为 performance 对象定义了两个属性。

  其中,performance.navigation 属性也是一个对象,包含着与页面导航有关的多个属性,如下所示

redirectCount:页面加载前的重定向次数。

type:数值常量,表示刚刚发生的导航类型。

performance.navigation.TYPE_NAVIGATE (0):页面第一次加载。
performance.navigation.TYPE_RELOAD (1):页面重载过。
performance.navigation.TYPE_BACK_FORWARD (2):页面是通过“后退”或“前进”按钮打开的。

 

nloadEventStart:前一个页面的 unload 事件开始的时间。但只有在前一个页面与当前页面来自同一个域时这个属性才会有值;否则,值为 0。

unloadEventEnd:前一个页面的 unload 事件结束的时间。但只有在前一个页面与当前页面来自同一个域时这个属性才会有值;否则,值为 0。

redirectStart:到当前页面的重定向开始的时间。但只有在重定向的页面来自同一个域时这个属性才会有值;否则,值为 0。

redirectEnd:到当前页面的重定向结束的时间。但只有在重定向的页面来自同一个域时这个属性才会有值;否则,值为 0

fetchStart:开始通过 HTTP GET 取得页面的时间

domainLookupStart:开始查询当前页面 DNS 的时间。

domainLookupEnd:查询当前页面 DNS 结束的时间。

connectStart:浏览器尝试连接服务器的时间。

connectEnd:浏览器成功连接到服务器的时间。

secureConnectionStart:浏览器尝试以 SSL 方式连接服务器的时间。不使用 SSL 方式连接时,这个属性的值为 0。

requestStart:浏览器开始请求页面的时间。

responseStart:浏览器接收到页面第一字节的时间

responseEnd:浏览器接收到页面所有内容的时间。

domLoading:document.readyState 变为"loading"的时间。

domInteractive:document.readyState 变为"interactive"的时间。

domContentLoadedEventStart:发生 DOMContentLoaded 事件的时间。

domContentLoadedEventEnd:DOMContentLoaded 事件已经发生且执行完所有事件处理程序的时间。

domComplete:document.readyState 变为"complete"的时间。

loadEventStart:发生 load 事件的时间。

loadEventEnd:load 事件已经发生且执行完所有事件处理程序的时间。

谷歌控制台打开如下:

8年javascript知识点积累  https://www.cnblogs.com/tylerdonet/p/5543813.html

函数柯里化在程序中的应用 (转载掘金 https://juejin.im/post/5be5b5a65188250fa835897e)

 1、编写轻松重用和配置的小代码块,就像我们使用npm一样:

  举个例子,比如你有一间士多店并且你想给你优惠的顾客给个10%的折扣(即打九折):

function discount(price, discount) {
    return price * discount
}

当一位优惠的顾客买了一间价值$500的物品,你给他打折:

const price = discount(500,0.10); // $50 
// $500  - $50 = $450

你可以预见,从长远来看,我们会发现自己每天都在计算10%的折扣:

const price = discount(1500,0.10); // $150
// $1,500 - $150 = $1,350
const price = discount(2000,0.10); // $200
// $2,000 - $200 = $1,800
const price = discount(50,0.10); // $5
// $50 - $5 = $45
const price = discount(5000,0.10); // $500
// $5,000 - $500 = $4,500
const price = discount(300,0.10); // $30
// $300 - $30 = $270

我们可以将discount函数柯里化,这样我们就不用总是每次增加这0.01的折扣。

function discount(discount) {
    return (price) => {
        return price * discount;
    }
}
const tenPercentDiscount = discount(0.1);

现在,我们可以只计算你的顾客买的物品的价格了:

tenPercentDiscount(500); // $50
// $500 - $50 = $450

同样地,有些优惠顾客比一些优惠顾客更重要-让我们称之为超级客户。并且我们想给这些超级客户提供20%的折扣。 可以使用我们的柯里化的discount函数:

const twentyPercentDiscount = discount(0.2);

我们通过这个柯里化的discount函数折扣调为0.2(即20%),给我们的超级客户配置了一个新的函数。 返回的函数twentyPercentDiscount将用于计算我们的超级客户的折扣:

twentyPercentDiscount(500); // 100
// $500 - $100 = $400
twentyPercentDiscount(5000); // 1000
// $5,000 - $1,000 = $4,000
twentyPercentDiscount(1000000); // 200000
// $1,000,000 - $200,000 = $600,000

2、避免频繁调用具有相同参数的函数

举个例子,我们有一个计算圆柱体积的函数

function volume(l, w, h) {
    return l * w * h;
}

碰巧仓库所有的气缸高度为100米,你将会看到你将重复调用此函数,h为100米

volume(200,30,100) // 2003000l
volume(32,45,100); //144000l
volume(2322,232,100) // 53870400l

要解决以上问题,你可以将volume函数柯里化(像我们之前做的):

function volume(h) {
    return (w) => {
        return (l) => {
            return l * w * h
        }
    }
}

我们可以定义一个专门指定圆柱体高度的的函数:

const hCylinderHeight = volume(100);
hCylinderHeight(200)(30); // 600,000l
hCylinderHeight(2322)(232); // 53,870,400l

通用的柯里化函数

我们来开发一个函数,它接受任何函数并返回一个柯里化版本的函数。 要做到这点,我们将有这个(虽然你的方法可能跟我的不一样):

function curry(fn, ...args) {
    return (..._arg) => {
        return fn(...args, ..._arg);
    }
}
上面代码做了什么?curry函数接受一个我们想要柯里化的函数(fn)和 一些可变数量的参数(…args)。剩下的操作用于将fn之后的参数数量收集到…args中。 然后,返回一个函数,同样地将余下的参数收集为…args。这个函数调用原始函数fn通过使用spread运算符作为参数传入... args和... args,然后,将值返回给使用。 现在我们可以用curry函数来创建特定的函数啦。 下面我们用curry函数来创建更多计算体检的特定函数(其中一个就是计算高度100米的圆柱体积函数)
function volume(l,h,w) {
    return l * h * w
}
const hCy = curry(volume,100);
hCy(200,900); // 18000000l
hCy(70,60); // 420000l
原文地址:https://www.cnblogs.com/he-qiang/p/8038883.html