JavaScript学习笔记(二十二)函数(二)
函数声明与函数表达式
- JavaScript引擎在任何代码执行之前,会先读取函数声明,并在执行上下文中生成函数定义。
- 函数表达式必须等到代码执行到它那一行,才会在执行上下文中生成函数定义。
- 函数声明提升:函数声明会在任何代码执行之前先被读取并添加到执行上下文。
- 在执行代码时,JavaScript引擎会先执行一遍扫描,把发现的函数声明提升到源代码树的顶部。
- 如果把代码中的函数声明改为等价的函数表达式,那么执行的时候就会出错
1 | // 没问题 |
- 以上代码出错的原因在于并没有执行到let定义函数那一行,并不是因为使用let造成的。
函数作为值
- 函数名在ECMAScript中就是变量。这意味着不仅可以把函数作为参数传给另一个函数,而且还可以在一个函数中返回另一个函数。
1 | function callSomeFunction(someFunction, someArgument) { |
函数内部
- 函数内部存在两个特殊的对象:arguments和this;一个属性new.target属性。
1、arguments
- arguments是一个类数组对象,包含调用函数时传入的所有参数。
- 只有以 function关键字定义函数(相对于使用箭头语法创建函数)时才会有。
- arguments对象其实还有一个callee属性,是一个指向arguments对象所在函数的指针。
- 使用arguments.callee可以让函数逻辑与函数名解耦
1 | function factorial(num) { |
2、this
- 在标准函数中,this引用的是把函数当成方法调用的上下文对象。
1 | window.color = 'red'; |
- 在箭头函数中,this引用的是定义箭头函数的上下文。
1 | window.color = 'red'; |
- 箭头函数中的this会保留定义该函数时的上下文
3、caller
- 这个属性引用的是调用当前函数的函数,或者如果是在全局作用域中调用的则为null。
1 | function outer() { |
- 同样可以通过arguments.callee.caller来降低耦合度。
1 | function outer() { |
- ECMAScript5也定义了arguments.caller,但在严格模式下访问它会报错,在非严格模式下则始终是undefined。
- 这是为了分清arguments.caller和函数的caller而故意为之的。
- 严格模式下还有一个限制,就是不能给函数的caller属性赋值,否则会导致错误。
new.target
- 如果函数是正常调用的则new.target的值是undefined;
- 如果是使用new关键字调用的,则new.target将引用被调用的构造函数。
1 | function King() { |
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 姚永坤的小窝!
评论