Published on

函数

Authors
  • avatar
    Name
    李丹秋
    Twitter

函数

函数也是一个对象,也是引用类型。函数名就是指向函数对象的指针。

function fun(){}
const fun1 = fun;
fun === fun1 true

函数名称

ES6会给每一个函数提供一个默认只读的name属性,作为函数的唯一标识

function fun(){}
const fun1 = fun;
fun.name == fun
fun1.name == fun

箭头函数

箭头函数虽然不支持 arguments 对象,但支持收集参数的定义方式,因此也可以实现与使用 arguments 一样的逻辑:

let getSum = (...values) => { 
 return values.reduce((x, y) => x + y, 0); 
}

函数声明和函数表达式

console.log(sum(10, 10)); 
function sum(num1, num2) { 
 return num1 + num2; 
}

以上代码可以正常运行,因为函数声明会在任何代码执行之前先被读取并添加到执行上下文。这个过程叫作函数声明提升

console.log(sum(10, 10)); 
let sum = function(num1, num2) { 
 return num1 + num2; 
};

函数表达式会报错,会按照脚本执行顺序执行。

this指向

在标准函数中,this 引用的是把函数当成方法调用的上下文对象。而在箭头函数中,this指向的是定义函数的上下文。

闭包

闭包指的是那些引用了另一个函数作用域中变量的函数 调用一个函数时,会为这个函数调用创建一个执行上下文,并创建一个作用域链。然后用 arguments和其他命名参数来初始化这个函数的活动对象。外部函数的活动对象是内部函数作用域链上的第二个对 象。这个作用域链一直向外串起了所有包含函数的活动对象,直到全局执行上下文才终止。 作用域链其实是一个包含指针的列表,每个指针分别指向一个变量对象,但物理上并不会包含相应的对象。

正常情况下,函数执行完成之后,局部活动对象会被销毁,内存中就只剩下全局作用域。但是闭包的函数因为始终保持着对函数活动对象的引用,所以无法被销毁,除非手动删除这种引用关系。

this对象

window.identity = 'The Window'; 
let object = { 
 identity: 'My Object', 
 getIdentityFunc() { 
 return function() { 
 return this.identity; 
 }; 
 } 
}; 

这段代码执行的结果是“The Window”,原因是匿名函数中的this指向并不是包含他的对象,而是getIdentityFunc执行完成之后返回的函数,再次执行时候的上下文已经是在全局中。

虽然一个函数不能直接访问它作用域链上其他函数的this,但是可以通过闭包的方式,获得this的引用

window.identity = 'The Window'; 
let object = { 
 identity: 'My Object', 
 getIdentityFunc() { 
 let that = this; 
 return function() { 
 return that.identity; 
 }; 
 } 
}; 
console.log(object.getIdentityFunc()()); // 'My Object'

或者可以使用上面提到的箭头函数,this指向的是定义函数的上下文,这样也能解决问题。

window.identity = 'The Window'; 
let object = { 
 identity: 'My Object', 
 getIdentityFunc() { 
 return ()=> { 
 return this.identity; 
 }; 
 } 
};