还有一个JavaScript范围问题。我认为这与提升'无关。
我这里有一小段代码 - http://jsfiddle.net/0oqLzsec/2/
var c = function(){
var x = 'before',
callBefore = function(){
alert(x);
},
callAfter = function(){
_callAfter();
};
return{
callBefore : callBefore,
callAfter : callAfter
}
var y = 'after';
function _callAfter(){
alert(y);
}
};
var obj = c();
obj.callBefore();
obj.callAfter();
callAfter()
始终提醒“未定义”'即使变量y在_callAfter()
之前定义。但是如果我在变量x之前移动变量y声明它正在工作。
我想知道下面定义的callAfter()
_callAfter()
是否可以Using MyConnection = New OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0;" + "Data Source=H:\Import\SER 2901 Fellow Cmts 063015B.xml;" + "Extended Properties=Excel 8.0;")
Using MyCommand = New OleDbDataAdapter("select * from [SER export$]", MyConnection)
Dim ds = New System.Data.DataSet
MyCommand.Fill(ds)
End Using
End Using
,为什么它不能读取变量y?
答案 0 :(得分:3)
_callAfter
和y
都被提升,这使得它们通过函数调用称为局部变量。 _callAfter
函数可以被调用(就像你一样),它也会关闭变量y
。但是,在从c
函数返回之前,此变量未获得值已分配。因此,你得到undefined
。如果您在返回前放置var y;
,并在返回后放置y='after';
,则相同。
换句话说,以下两个是等价的:
function foo(){
var a;
return function(){ return a };
a = 42; // never runs
}
alert( foo()() );
function bar(){
return function(){ return a };
var a = 42;
}
alert( bar()() );

这是一个示例,显示局部变量被提升并关闭,即使函数文字出现在代码中的var
之前:
function build() {
return function(newValue) {
alert("was: " + oldValue);
oldValue = newValue;
alert("now: " + oldValue);
}
var oldValue = 42;
}
f = build();
f(17);
// was: undefined
// now: 17
f(99);
// was: 17
// now: 99

答案 1 :(得分:2)
它与提升有关,var y
被移动到函数的顶部,但是赋值(y = 'after'
)不是,所以它永远不会运行,因为它在{{{{1}之后1}}。
JS引擎将您的代码重写为:
return statement