diff --git a/docs/class.md b/docs/class.md index ddfe4c8..dc2ec1e 100644 --- a/docs/class.md +++ b/docs/class.md @@ -581,7 +581,7 @@ B.__proto__ = A; 这两条继承链,可以这样理解:作为一个对象,子类(`B`)的原型(`__proto__`属性)是父类(`A`);作为一个构造函数,子类(`B`)的原型(`prototype`属性)是父类的实例。 ```javascript -bject.create(A.prototype); +Object.create(A.prototype); // 等同于 B.prototype.__proto__ = A.prototype; ``` diff --git a/docs/function.md b/docs/function.md index 651a598..95e4d8d 100644 --- a/docs/function.md +++ b/docs/function.md @@ -242,7 +242,7 @@ function f(y = x) { f() // 1 ``` -上面代码中,函数调用时,`y`的默认值变量`x`尚未在函数内部生成,所以`x`指向全局变量,结果又不一样。 +上面代码中,函数调用时,`y`的默认值变量`x`尚未在函数内部生成,所以`x`指向全局变量。 如果此时,全局变量`x`不存在,就会报错。 @@ -269,7 +269,7 @@ foo() // ReferenceError: x is not defined 上面代码中,函数`foo`的参数`x`的默认值也是`x`。这时,默认值`x`的作用域是函数作用域,而不是全局作用域。由于在函数作用域中,存在变量`x`,但是默认值在`x`赋值之前先执行了,所以这时属于暂时性死区(参见《let和const命令》一章),任何对`x`的操作都会报错。 -如果函数`A`的参数默认值是函数`B`,由于函数的作用域是其声明时所在的作用域,那么函数`B`的作用域不是函数`A`,而是全局作用域。请看下面的例子。 +如果参数的默认值是一个函数,该函数的作用域是其声明时所在的作用域。请看下面的例子。 ```javascript let foo = 'outer'; @@ -282,19 +282,7 @@ function bar(func = x => foo) { bar(); ``` -上面代码中,函数`bar`的参数`func`,默认是一个匿名函数,返回值为变量`foo`。这个匿名函数的作用域就不是`bar`。这个匿名函数声明时,是处在外层作用域,所以内部的`foo`指向函数体外的声明,输出`outer`。它实际上等同于下面的代码。 - -```javascript -let foo = 'outer'; -let f = x => foo; - -function bar(func = f) { - let foo = 'inner'; - console.log(func()); // outer -} - -bar(); -``` +上面代码中,函数`bar`的参数`func`的默认值是一个匿名函数,返回值为变量`foo`。这个匿名函数声明时,`bar`函数的作用域还没有形成,所以匿名函数里面的`foo`指向外层作用域的`foo`,输出`outer`。 如果写成下面这样,就会报错。 @@ -307,6 +295,36 @@ function bar(func = () => foo) { bar() // ReferenceError: foo is not defined ``` +上面代码中,匿名函数里面的`foo`指向函数外层,但是函数外层并没有声明`foo`,所以就报错了。 + +下面是一个更复杂的例子。 + +```javascript +var x = 1; +function foo(x, y = function() { x = 2; }) { + var x = 3; + y(); + console.log(x); +} + +foo() // 3 +``` + +上面代码中,函数`foo`的参数`y`的默认值是一个匿名函数。函数`foo`调用时,它的参数`x`的值为`undefined`,所以`y`函数内部的`x`一开始是`undefined`,后来被重新赋值`2`。但是,函数`foo`内部重新声明了一个`x`,值为`3`,这两个`x`是不一样的,互相不产生影响,因此最后输出`3`。 + +如果将`var x = 3`的`var`去除,两个`x`就是一样的,最后输出的就是`2`。 + +```javascript +var x = 1; +function foo(x, y = function() { x = 2; }) { + x = 3; + y(); + console.log(x); +} + +foo() // 2 +``` + ### 应用 利用参数默认值,可以指定某一个参数不得省略,如果省略就抛出一个错误。