- 参数默认值
arguments
- length不包括rese参数(…values)
- length不包括赋默认值参数(values=1)
1
2console.log((function A(a,dm,s,...v){}).length) // 3
console.log((function A(a,dm,s,v=1){}).length) // 3
作用域
必输参数
1
2
3
4
5
6function throwMiss(){
throw new Error('arguments error')
}
function gg(x=throwMiss()){ console.log(x)}
gg(2) // 2
gg() // arguments errorrest参数
1
2
3
4
5
6
7
8
9function add(...values){
//...values == [2,3,4,5] 从参数末尾索引开始计算,截止到最后一个有效参数索引为止
let sum = 0;
for (var val of values){
sum += val;
}
return sum;
}
add(2,3,4,5);扩展运算符…
1
2
3
4
5console.log(...[1,5,6]) // 1 5 6
console.log(...[1,[5,6]]) // 1 [5,6]
console.log(...[1,...[5,6]]) // 1 5 6
console.log(...{'0':'12','1':'34',length:2}) // 12 34
* 凡是涉及到操作32位Unicode字符的函数‘x\uD83D\uDE80y’.length // 4 wrong
[…’x\uD83D\uDE80y’].length // 3 right
function length(str){ return […str].length}1
2
3
4
5
6
7* map, generator function可以使用...
* 如果对没有iterator接口的对象,使用扩展运算符,将会报错
* 箭头函数
*函数体内的this对象,就是定义时所在的对象,而不是使用时所在的对象。
*不可以当作构造函数,也就是说,不可以使用new命令,否则会抛出一个错误。
*不可以使用arguments对象,该对象在函数体内不存在。如果要用,可以用Rest参数代替。
*不可以使用yield命令,因此箭头函数不能用作Generator函数。function Timer () {
this.s1 = 14; this.s2 = 4; // 箭头函数 // this指向定义时所在作用域,即Timer setInterval(() => this.s1++, 1000); // 普通函数 // this指向执行时作用域,即window setInterval(function () { this.s2++; }, 1000);
}
1
* 箭头函数可以让this指向固定化
var handler = {
id: '123456', init: function() { //this指向handler,因为=>没有自己的this(this == undefined),所以指向最近的外部this document.addEventListener('click', event => this.doSomething(event.type), false); // var self = this; // document.addEventListener('click',function(){ // self.doSomething(event.type) // },false) }, doSomething: function(type) { console.log('Handling ' + type + ' for ' + this.id); }
};
1
* call\apply\bind无效,会忽略
(function() {
return [ (() => this.x).bind({ x: 'inner' })() ]
}).call({ x: ‘outer’ });
// function () {
// var _this = this;
// return [function () {
// return _this.x;
// }.bind({ x: ‘inner’ })()];
// }.call({ x: ‘outer’ })1
* :: 返回的是原对象
//上下文::执行方法
foo::bar;
// 等同于
bar.bind(foo);foo::bar(…arguments);
// 等同于
bar.apply(foo, arguments);const hasOwnProperty = Object.prototype.hasOwnProperty;
function hasOwn(obj, key) {return obj::hasOwnProperty(key);
}
1
2
3* 尾调=>调用栈
* stack overflow 栈溢出
* 尾递归//复杂度O(n)
function factorial(n) {if (n === 1) return 1; return n * factorial(n - 1);
}
factorial(5) // 120
//5 factorial(4)
//5 (4 factorial(3))
//5 (4 (3 factorial(2)))
//5 (4 (3 (2 factorial(1))))
//5 4 3 2 1
//复杂度O(1)
function factorial(n, total){if(n === 1) return total; return factorial(n-1, n * total);
}
factorial(5,1) // 120
// 只保留一个调用帧
// factorial(5,1)
// factorial(4,5)
// factorial(3,20)
// factorial(2,60)
// factorial(1,120)1
2
3
4`
尾递归的实现,往往需要改写递归函数,确保最后一步只调用自身。做到这一点的方法,就是把所有用到的内部变量改写成函数的参数。比如上面的例子,阶乘函数 factorial 需要用到一个中间变量 total ,那就把这个中间变量改写成函数的参数。
`
* 闭包记忆 [简书资料](http://www.jianshu.com/p/a2dfa59e70d7)
//cache为function内局部变量,cache被匿名函数引用,匿名函数上下文为全局变量window
//memorize执行完后,cache理应被回收,但是在被匿名函数引用的情况下无法回收
function memorize(sets, f) {
var cache = {};
return function (x) {
console.log(‘cache: %j’, cache);
return x in cache
? cache[x]
: cache[x] = f(sets[x]);
}
}
var g = memorize([1000, 2000, 3000], function (x) { return x * x; });
````
- console.log(‘%c Hello~how are you’,’font-size:28px; font-family:Microsoft YAHEI;color: blue; font-weight: bold;’)
/Object/
- Object.assign
- //除了字符串会以数组形式拷贝入目标对象,数值、布尔、undefined、null都不起效果(这是因为只有字符串的包装对象,会产生可枚举属性)
- //首参数不能是Null、Undefined :Cannot convert undefined or null to object