您观察到的称为词法范围。这意味着JavaScript中某个范围内的变量的绑定是由变量在代码中出现的位置决定的。它总是正确的,在任何层面上都是正确的。唯一的主要例外是this
值,它是动态作用域而不是词法作用域。动态范围意味着函数中的变量取决于调用函数的方式和时间。(请参阅词汇范围和动态范围。)
例子:
var o = {
a: function() {
var x = 5;
console.log(this, x);
function b() {
console.log(this, x);
}
b();
}
};
o.a();
此示例的结果将是:
{Object o} 5
{window} 5
换句话说,第一个console.log
将记录this
为对o
对象的引用,而第二个console.log
将记录this
为对window
对象的引用。但是,两者都将记录x
为等于5
。的值this
是window
在没有上下文的非严格模式下调用它时。所以this
不是词法范围的,而是其他变量,比如x
。要了解有关行为的更多信息,this
请参阅A Short Overview ofthis
.
直接回答您的问题:
1. 首先,这总是正确的吗?还是有严格的条件?(比如,它必须是一个对象吗?等等)
this
是的,这是真的,除了arguments
基于函数调用方式的变化。它不必是一个对象,所有变量都是词法范围的。
2. 另外,javascript 中还有哪些类似这样的晦涩作用域?我很想知道(即第三次迭代呢?)
您可以随心所欲地深入——内部函数始终可以访问其外部函数的变量。
function a() {
var x = 1;
console.log('a:', x);
return function b() {
var y = 2;
console.log('b:', x, y);
return function c() {
console.log('c:', x, y);
};
};
}
var foo = a(); // => logs 'a: 1'
var bar = foo(); // => logs 'b: 1 2'
bar(); // => logs 'c: 1 2'
这实际上是另一个称为闭包的主题的一部分,当您从另一个函数中返回一个函数时会发生这种情况。
3. 最后,我可以阅读一份解释 javascript 范围的高级概念的文档。有谁知道有什么好的吗?
我已经链接到几个资源。另一个不错的:
MDN:函数和函数范围(特别是关于嵌套函数和闭包的部分)。
此外,阅读有关闭包的任何内容都会使您受益,并且您可能还想查找词法范围。