据我所知,一个函数说在另一个函数中定义的A表示B也可以访问B的局部变量.
function B() {
var x = 10;
function A() {
console.log(x); //will result in 10
var y = 5;
}
console.log(y); //ReferenceError: y is not defined
}
Run Code Online (Sandbox Code Playgroud)
但是在下面的例子中,y被打印出来.我知道javascript中的块范围没有"if block"这样的东西,但是在"if"之外的一个声明至少是不可见的,我的意思是不应该限制为if block?
function B() {
var x = 10;
if(1) {
console.log(x); //will result in 10
var y = 5;
}
console.log(y); will result in 5
}
Run Code Online (Sandbox Code Playgroud)
JavaScript不是真正的块范围.一个if或for循环没有自己的范围.任何给定范围内的所有变量声明(即:全局范围或函数)都会被提升,并且在该范围内的任何位置都可见.
ECMAScript6(Harmony)很可能会通过使用new let关键字向JS引入块范围,请参阅wiki:
for (let i=0;i<12;++i)
{
console.log(i);//logs i
}
console.log(i);//reference error
Run Code Online (Sandbox Code Playgroud)
就术语而言,似乎也存在一些混淆:闭包与范围不同.
上面的代码段是块范围代码的示例.变量i在循环开始时创建,并且在循环结束后简单地停止存在.它是GC(垃圾收集).i不再是,失去生命,它依赖于和平.闭包是完全不同的:它们依赖于非GC的变量,但无法从外部代码访问.它们只能通过闭包的返回值来访问:
var someClosure = (function()
{//this function creates a scope
var x = 123;
return {
getX: function()
{
return x;
},
setX: function(val)
{
return x = val;
}
};
}());
console.log(x);//reference error
console.log(someClosure.getX());//returns 123, so "x" still exists
Run Code Online (Sandbox Code Playgroud)
话虽这么说:但是
你可以通过使用闭包来模仿块范围的循环.函数是作用域的,闭包是函数返回的函数或对象.这意味着函数的返回值可以访问整个函数的范围.有关详情,请参阅此答案.
应用那里解释的,并找出为什么这个循环是"伪范围":
var foo = [1,2,3,4,5,6],
largerThan3 = (function(arr)
{
var resultArr = [];
for (var i=0;i<arr.length;++i)
{
if (arr[i] > 3)
resultArr.push(arr[i]);
}
return resultArr;
}(foo));
console.log(i);//reference error...
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
182 次 |
| 最近记录: |