JavaScript 对象的原型,在用户层面的代码看到的是 __proto__
属性,在语言内部是 [[prototype]]
属性。aConstructorFn.prototype
是指原型链。
一个对象的原型是一个对象,或者是 null。Object 这个对象的原型链的原型(Object.prototype.__proto__
)是 null
。
所以一个默认的对象不是空的,因为继承了 Object.prototype
的属性,如果需要创建一个无属性的空对象,需要显式把其原型设为 null
,这可以通过 Object.create(null)
或 anObj.__proto__ = null
来设置。
每个执行上下文(execution context)都有一个关联的词法环境,其堆栈是一个先进先出的队列,维护控制流和执行顺序。
函数式第一级别(First-class function)意味着函数可以被被当作普通数据来使用,如存储为变量,作为参数传递和作为函数返回值。
自由变量(Free variable)是指不是参数也不是函数内局部变量的变量。这涉及到自由变量中取定义时的环境的值还是运行时的环境的值?JavaScript 中是取定义时的,即看源码即可确定(静态作用域 static scope)。
JavaScript 中除了 this
1,其余都是静态作用域。
//(把函数作为参数)downwards funarg problem
let x = 10;
function foo() {
console.log(x);
}
function bar(funArg) {
let x = 20;
funArg(); // 10, not 20!
}
// Pass `foo` as an argument to `bar`.
bar(foo);
// (返回函数)upwards funarg problem
function foo() {
let x = 10;
// Closure, capturing environment of `foo`.
function bar() {
return x;
}
// Upward funarg.
return bar;
}
let x = 20;
// Call to `foo` returns `bar` closure.
let bar = foo();
bar(); // 10, not 20!
闭包是指包含了函数及其定义时的环境的记录(也有认为是指包含了定义时环境的函数)。理论上所有函数都是,但如果一个函数没使用到自由变量,那么实际上可以优化掉这个外部环境。