An object is a collection of properties and has a single prototype object. The prototype may be either an object or the null value.
Object是一个属性的集合,并且都拥有一个单独的原型对象[prototype object]. 这个原型对象[prototype object]可以是一个object或者null值。
var foo = {
x: 10,
y: 20
};
A prototype chain is a finite chain of objects which is used to implemented inheritance and shared properties.
原型链是一个由对象组成的有限对象链由于实现继承和共享属性。
var a = {
x: 10,
calculate: function (z) {
return this.x + this.y + z
}
};
var b = {
y: 20,
__proto__: a
};
var c = {
y: 30,
__proto__: a
};
// 调用继承过来的方法
b.calculate(30); // 60
c.calculate(40); // 80
// 构造函数
function Foo(y) {
// 构造函数将会以特定模式创建对象:被创建的对象都会有"y"属性
this.y = y;
}
// "Foo.prototype"存放了新建对象的原型引用
// 所以我们可以将之用于定义继承和共享属性或方法
// 所以,和上例一样,我们有了如下代码:
// 继承属性"x"
Foo.prototype.x = 10;
// 继承方法"calculate"
Foo.prototype.calculate = function (z) {
return this.x + this.y + z;
};
// 使用foo模式创建 "b" and "c"
var b = new Foo(20);
var c = new Foo(30);
// 调用继承的方法
b.calculate(30); // 60
c.calculate(40); // 80
// 让我们看看是否使用了预期的属性
console.log(
b.__proto__ === Foo.prototype, // true
c.__proto__ === Foo.prototype, // true
// "Foo.prototype"自动创建了一个特殊的属性"constructor"
// 指向a的构造函数本身
// 实例"b"和"c"可以通过授权找到它并用以检测自己的构造函数
b.constructor === Foo, // true
c.constructor === Foo, // true
Foo.prototype.constructor === Foo // true
b.calculate === b.__proto__.calculate, // true
b.__proto__.calculate === Foo.prototype.calculate // true
);
function foo(bar) {}
// 调用相同的function,每次都会产生3个不同的上下文
//(包含不同的状态,例如参数bar的值)
foo(10);
foo(20);
foo(30);
A variable object is a scope of data related with the execution context.
It’s a special object associated with the context and which stores variables and function declarations are being defined within the context.
变量对象(variable object) 是与执行上下文相关的 数据作用域(scope of data) 。
它是与上下文关联的特殊对象,用于存储被定义在上下文中的 变量(variables) 和 函数声明(function declarations) 。
var foo = 10;
function bar() {} // // 函数声明
(function baz() {}); // 函数表达式
console.log(
this.foo == foo, // true
window.bar == bar // true
);
console.log(baz); // 引用错误,baz没有被定义
function foo(x, y) {
var z = 30;
function bar() {} // 函数声明
(function baz() {}); // 函数表达式
}
foo(10, 20);
A scope chain is a list of objects that are searched for identifiers appear in the code of the context.
作用域链是一个 对象列表(list of objects) ,用以检索上下文代码中出现的 标识符(identifiers) 。
var x = 10;
(function foo() {
var y = 20;
(function bar() {
var z = 30;
// "x"和"y"是自由变量
// 会在作用域链的下一个对象中找到(函数”bar”的互动对象之后)
console.log(x + y + z);
})();
})();
Object.prototype.x = 10;
var w = 20;
var y = 30;
// 在SpiderMonkey全局对象里
// 例如,全局上下文的变量对象是从"Object.prototype"继承到的
// 所以我们可以得到“没有声明的全局变量”
// 因为可以从原型链中获取
console.log(x); // 10
(function foo() {
// "foo" 是局部变量
var w = 40;
var x = 100;
// "x" 可以从"Object.prototype"得到,注意值是10哦
// 因为{z: 50}是从它那里继承的
with ({z: 50}) {
console.log(w, x, y , z); // 40, 10, 30, 50
}
// 在"with"对象从作用域链删除之后
// x又可以从foo的上下文中得到了,注意这次值又回到了100哦
// "w" 也是局部变量
console.log(x, w); // 100, 40
// 在浏览器里
// 我们可以通过如下语句来得到全局的w值
console.log(window.w); // 20
})();
Scope chain = Activation object + [[Scope]]
作用域链 = 活动对象 + [[Scope]]
function foo() {
var x = 10;
return function bar() {
console.log(x);
};
}
// "foo"返回的也是一个function
// 并且这个返回的function可以随意使用内部的变量x
var returnedFunction = foo();
// 全局变量 "x"
var x = 20;
// 支持返回的function
returnedFunction(); // 结果是10而不是20
// 全局变量 "x"
var x = 10;
// 全局function
function foo() {
console.log(x);
}
(function (funArg) {
// 局部变量 "x"
var x = 20;
// 这不会有歧义
// 因为我们使用"foo"函数的[[Scope]]里保存的全局变量"x",
// 并不是caller作用域的"x"
funArg(); // 10, 而不是20
})(foo); // 将foo作为一个"funarg"传递下去
A closure is a combination of a code block (in ECMAScript this is a function) and statically/lexically saved all parent scopes.
Thus, via these saved scopes a function may easily refer free variables.
闭包是一系列代码块(在ECMAScript中是函数),并且静态保存所有父级的作用域。通过这些保存的作用域来搜寻到函数中的自由变量。
function baz() {
var x = 1;
return {
foo: function foo() { return ++x; },
bar: function bar() { return --x; }
};
}
var closures = baz();
console.log(
closures.foo(), // 2
closures.bar() // 1
);
var data = [];
for (var k = 0; k < 3; k++) {
data[k] = function () {
alert(k);
};
}
data[0](); // 3, but not 0
data[1](); // 3, but not 1
data[2](); // 3, but not 2
var data = [];
for (var k = 0; k < 3; k++) {
data[k] = (function (x) {
return function () {
alert(x);
};
})(k); // 将k当做参数传递进去
}
// 结果正确
data[0](); // 0
data[1](); // 1
data[2](); // 2
A this value is a special object which is related with the execution context.
Therefore, it may be named as a context object (i.e. an object in which context the execution context is activated).
this适合执行的上下文环境息息相关的一个特殊对象。因此,它也可以称为上下文对象[context object](激活执行上下文的上下文)。
a this value is a property of the execution context, but not a property of the variable object.
this是执行上下文环境的一个属性,而不是某个变量对象的属性
var x = 10;
console.log(
x, // 10
this.x, // 10
window.x // 10
);
// "foo"函数里的alert没有改变
// 但每次激活调用的时候this是不同的
function foo() {
alert(this);
}
// caller 激活 "foo"这个callee,
// 并且提供"this"给这个 callee
foo(); // 全局对象
foo.prototype.constructor(); // foo.prototype
var bar = {
baz: foo
};
bar.baz(); // bar
(bar.baz)(); // also bar
(bar.baz = bar.baz)(); // 这是一个全局对象
(bar.baz, bar.baz)(); // 也是全局对象
(false || bar.baz)(); // 也是全局对象
var otherFoo = bar.baz;
otherFoo(); // 还是全局对象