为什么使用this
先看个例子:
function identity() {
return this.name.toUpperCase();
}
function speak() {
return "Hello, i'm " + identity.call(this);
}
var me = {
name: 'rod chen'
}
var you = {
name: "others in Aug"
}
console.log(identity.call(me)); //ROD CHEN
console.log(identity.call(you)); //OTHERS IN AUG
console.log(speak.call(me)); //Hello, i'm ROD CHEN
console.log(speak.call(you)); //Hello, i'm OTHERS IN AUG
输出的结果很明显,对于call的用法前面文章有提到,第一个参数就是传入到函数里的this的值。这段代码可以在不同的上下文对象( me 和 you )中重复使用函数 identify() 和 speak() ,如果我们不适用this的话,那就需要identity和speak显示传入一个上下文对象,就像下面的方式
function identity(context) {
return context.name.toUpperCase();
}
function speak(context) {
return "Hello, i'm " + identity(context);
}
var me = {
name: 'rod chen'
}
var you = {
name: "others in Aug"
}
console.log(identity(me));
console.log(identity(you));
console.log(speak(me));
console.log(speak(you));
总结:
this 提供了一种更优雅的方式来隐式“传递”一个对象引用,因此可以将API设计得更加简洁并且易于复用。随着使用模式越来越复杂,显式传递上下文对象会让代码变得越来越混乱,使用 this 则不会这样
Reference
ECMAScript 的类型分为语言类型和规范类型。
ECMAScript 语言类型是开发者直接使用 ECMAScript 可以操作的。其实就是我们常说的Undefined, Null, Boolean, String, Number, 和 Object。
而规范类型相当于 meta-values,是用来用算法描述 ECMAScript 语言结构和 ECMAScript 语言类型的。规范类型包括:Reference, List, Completion, Property Descriptor, Property Identifier, Lexical Environment, 和 Environment Record。
没懂?没关系,我们只要知道在 ECMAScript 规范中还有一种只存在于规范中的类型,它们的作用是用来描述语言底层行为逻辑。
Reference 类型就是用来解释诸如 delete、typeof 以及赋值等操作行为的
这里的 Reference 是一个 Specification Type,也就是 “只存在于规范里的抽象类型”。它们是为了更好地描述语言的底层行为逻辑才存在的,但并不存在于实际的 js 代码中。
组成
这段讲述了 Reference 的构成,由三个组成部分,分别是:
- base value
- referenced name
- strict reference
可是这些到底是什么呢?
我们简单的理解的话:
base value 就是属性所在的对象或者就是 EnvironmentRecord,它的值只可能是 undefined, an Object, a Boolean, a String, a Number, or an environment record 其中的一种。
referenced name 就是属性的名称。
var foo = 1;
// 对应的Reference是:
var fooReference = {
base: EnvironmentRecord,
name: 'foo',
strict: false
};
var foo = {
bar: function () {
return this;
}
};
foo.bar(); // foo
// bar对应的Reference是:
var BarReference =