深入理解Functions
在ECMAScript 5里,function内部有两个特殊的objects:arguments和this。在ECMAScript 6里,又引入了new.target属性。
arguments对象
this对象
在标准函数和箭头函数中,this的指向是不同的。
在标准函数中,this指向函数被绑定的对象(context object)。
在箭头函数中,this指向函数表达式被定义的上下文(context)。
identity = 'The Window';
let object = {
identity: 'My Object',
getIdentity () {
return this.identity;
}
};
const result1 = object.getIdentity();
const result2 = (object.getIdentity)();
console.log(result1); //My Object
console.log(result2); //My Object
const result3 = (object.getIdentity = object.getIdentity)()
console.log(result3); //The Window
caller属性
new.target属性
可以通过Function的constructor来实例一个新对象,也可以作为普通函数来调用。
new.target用来判断是否使用了new关键字来调用函数。
function King() {
if (!new.target) {
throw 'King must be instantiated using "new"'
}
console.log('King instantiated using "new"';
}
new King(); // King instantiated using "new"
King(); // Error: King must be instantiated using "new"
length属性
用来表示该函数期望接收的有名参数(named arguments)的个数。
举例:
function sayName(name) {
console.log(name);
}
function sum(num1, num2) {
return num1 + num2;
}
function sayHi() {
console.log("hi");
}
console.log(sayName.length); // 1
console.log(sum.length); // 2
console.log(sayHi.length); // 0
prototype属性
作用域链
当一个function被调用时,就会为他创建一个执行上下文(execution context)和作用域链(scope chain)。其中作用域链中的第一级是该function的活跃对象(activation object),它包含了arguments和所有的有名参数(named arguments);第二级是外部函数的activation object,以此类推,最后一级是全局执行上下文的 (global execution context)的variable object。
作用域链本质上是指向variable objects的指针列表。
function createComparisonFunction(propertyName) {
return function(object1, object2) {
let value1 = object1[propertyName];
let value2 = object2[propertyName];
if (value1 < value2) {
return -1;Closures ❘ 377
} else if (value1 > value2) {
return 1;
} else {
return 0;
}
};
}
let compare = createComparisonFunction('name');
let result = compare({ name: 'Nicholas' }, { name: 'Matt' });
当createComparisonFunction函数执行完毕后,它的执行上下文的作用域链(scope chain )会被销毁,但是它的activation object仍会保留在内存中、直到它内部的匿名函数被销毁掉。
// create function
let compareNames = createComparisonFunction('name');
// call function
let result = compareNames({ name: 'Nicholas' }, { name: 'Matt' });
// dereference function - memory can now be reclaimed
compareNames = null;
网友评论