第六章 数值的扩展
(为什么没写第五章呢,因为正则的东西实在是渣啊,之前偶尔用到正则,都是去网上找的正则表达式,所以就随他去吧....)
好吧第六章也没有什么代码可记,基本都是在介绍新增的一些number的方法以及math的方法,多加练习吧,用的多了自然会记住这些函数。
第七章 函数的扩展
// 不报错
function foo(x, x, y) {
// ...
}
// 报错
function foo(x, x, y = 1) {
// ...
}
// SyntaxError: Duplicate parameter name not allowed in this context
尝试了一下,在不报错的情况下,我调用这个函数的时候,用foo(1,2,3)分别赋值,则x = 2;只给第一个x赋值,foo(1),则x = undefined,也就是说无论如何第一个x都会被第二个x覆盖掉。个人理解,函数内其实还是只有一个x和一个y,定义了两次之后,不管第一个值是多少,都被第二次的定义给盖掉了。但是这又牵扯到另外一个问题,let不允许重名。。。先记住吧,实际效果是这样的。
// 写法一
function m1({x = 0, y = 0} = {}) {
return [x, y];
}
// 写法二
function m2({x, y} = { x: 0, y: 0 }) {
return [x, y];
}
// 函数没有参数的情况
m1() // [0, 0]
m2() // [0, 0]
// x 和 y 都有值的情况
m1({x: 3, y: 8}) // [3, 8]
m2({x: 3, y: 8}) // [3, 8]
// x 有值,y 无值的情况
m1({x: 3}) // [3, 0]
m2({x: 3}) // [3, undefined]
// x 和 y 都无值的情况
m1({}) // [0, 0];
m2({}) // [undefined, undefined]
m1({z: 3}) // [0, 0]
m2({z: 3}) // [undefined, undefined]
跟想的一样,其实是对之前解构那一章的一个复习。
var x = 1;
function foo(x, y = function() { x = 2; }) {
var x = 3;
y();
console.log(x);
}
foo() // 3
x // 1
foo() = 3是因为,y函数里面的x是个局部变量,指向同一个作用域的第一个参数x,也就是foo(x,y)的x,console.log(x)已经出了这个作用域,console这一句的x是此作用域下的var x = 3,所以打印出来的是3.后面单取x的时候,因为出了foo函数,所以var x = 3的作用域也过去了,此时是var x = 1的作用域,所以是1。
var x = 1;
function foo(x, y = function() { x = 2; }) {
x = 3;
y();
console.log(x);
}
foo() // 2
x // 1
如果将var x = 3
的var
去除,函数foo
的内部变量x
就指向第一个参数x
,与匿名函数内部的x
是一致的,所以最后输出的就是2
,而外层的全局变量x
依然不受影响。
// 报错
function doSomething(a, b = a) {
'use strict';
// code
}
// 报错
const doSomething = function ({a, b}) {
'use strict';
// code
};
// 报错
const doSomething = (...a) => {
'use strict';
// code
};
const obj = {
// 报错
doSomething({a, b}) {
'use strict';
// code
}
};
ES2016 做了一点修改,规定只要函数参数使用了默认值、解构赋值、或者扩展运算符,那么函数内部就不能显式设定为严格模式,否则会报错。
function Timer() {
this.s1 = 0;
this.s2 = 0;
// 箭头函数
setInterval(() => this.s1++, 1000);
// 普通函数
setInterval(function () {
this.s2++;
}, 1000);
}
var timer = new Timer();
setTimeout(() => console.log('s1: ', timer.s1), 3100);
setTimeout(() => console.log('s2: ', timer.s2), 3100);
// s1: 3
// s2: 0
上面代码中,
Timer
函数内部设置了两个定时器,分别使用了箭头函数和普通函数。前者的
this
绑定定义时所在的作用域(即
Timer
函数),后者的
this
指向运行时所在的作用域(即全局对象)。所以,3100 毫秒之后,
timer.s1
被更新了 3 次,而
timer.s2
一次都没更新。
function foo() {
return () => {
return () => {
return () => {
console.log('id:', this.id);
};
};
};
}
var f = foo.call({id: 1});
var t1 = f.call({id: 2})()(); // id: 1
var t2 = f().call({id: 3})(); // id: 1
var t3 = f()().call({id: 4}); // id: 1
关于this的内容需要再回去翻翻书了,绕晕。。。
ES6书中解释,上面代码之中,只有一个this
,就是函数foo
的this
,所以t1
、t2
、t3
都输出同样的结果。因为所有的内层函数都是箭头函数,都没有自己的this
,它们的this
其实都是最外层foo
函数的this
。
// 情况一
function f(x){
let y = g(x);
return y; //不是尾调用
}
// 情况二
function f(x){
return g(x) + 1; //不是尾调用
}
// 情况三
function f(x){
g(x); //不是尾调用,因为后面隐含了一步return undefined
}