1.函数声明与函数表达式:
JavaScript引擎在加载数据时对函数声明和函数表达式是区别对待的。
函数声明:JavaScript引擎在任何代码执行之前,会先读取函数声明,并在执行上下文中生成函数定义。
函数表达式:函数表达式必须等到代码执行到它那一行,才会在执行上下文中生成函数定义。
console.log(sum(10, 10));
function sum(num1, num2) {
return num1 + num2;
}
//没问题
以上代码可以正常运行,因为函数声明会在任何代码执行之前先被读取并添加到执行上下文,这个过程叫做函数声明提升。在执行代码时,JavaScript引擎会先执行一遍扫描,把发现的函数声明提升到源代码树的顶部。因此即使函数定义出现在调用它们的代码之后,引擎也会把函数声明提升到顶部。
console.log(sum(10, 10));
let sum = function(num1, num2) {
return num1 + num2;
};
//会出错
上面是与前面代码等价的函数表达式,之所以会出错是因为这个函数定义包含在一个变量初始化语句中,而不是函数声明。这意味着如果代码没有执行到变量初始化的那一行,那么执行上下文中就没有函数的定义,所以上面代码会出错。使用var关键字同样会出错。
2.函数作为值:
因为函数名在ECMAScript中就是变量,所以函数可以用在任何可以使用变量的地方,不仅可以把函数作为参数传给另一个函数,而且还可以在一个函数中返回另一个函数。
其中,如果是访问函数而不是调用函数,那就必须不带括号,即:
访问函数:sum
调用函数:sum()
3.函数内部:
在ECMAScript 5 中,函数内部存在两个特殊的对象:arguments和this。ECMAScript 6 又新增了new.target属性。
3.1 arguments:
arguments是一个类数组对象,包含调用函数时传入的所有参数,这个对象只有以function关键字定义函数时才会有。
arguments有一个callee属性,是一个指向arguments对象所在函数的指针。
3.2 this:
this在标准函数和箭头函数中有不同的行为。
在标准函数中:this引用的是把函数当成方法调用的上下文对象。(在网页的全局上下文中调用函数时,this指向windows)
在箭头函数中:this引用的是定义箭头函数的上下文。
3.3 new.target:
ECMAScript中的函数始终可以作为构造函数实例化一个新对象,也可以作为普通函数被调用。
ECMAScript 6 新增了检测函数是否使用new关键字调用的new.target属性,如果函数是正常调用的,则new.target的值是undefined,如果是使用new关键字调用的,则new.target将引用被调用的构造函数。