Javascript 范围和提升的混淆
Confusion about scope and hoisting in Javascript
<!DOCTYPE>
<html>
<head>
<link rel="stylesheet" href="styles.css"/>
<body>
<ul id="people-list"></ul>
<script src="app.js"/>
</body>
</head>
</html>
***app.js***
var people = ["alf","kay","jay","may"];
var list = document.getElementById("people-list");
for(var i =0; i< people.length; i++){
var person = people[i];
var element = document.createElement("li");
(function (){
var person = person;
element.innerText = person;
element.addEventListener("click",function(){
alert("You clicked on "+ person);
});
}());
list.appendChild(element);
}
为什么在全局作用域中创建的 "person" 变量没有在 IIFE 中被引用,因此产生了一个未定义的列表,然后变量名从(例如 var person 到 var person2 和后续IIFE 中警报的更改)使代码正常工作。
由于吊装var person = person
正好等同于
var person;
person = person;
您不能在外部范围内引用 person
变量。它完全被局部变量遮盖了,所以你把未定义的局部变量赋给它自己。
Why is the "person" variable created in the Global Scope not being referenced in the IIFE
因为您在 IIFE 的范围内有一个 person
变量,它掩盖了它。
如果你有两个同名的变量,在不同的范围内,你只能访问在最近的范围内声明的那个。
提升在这里没有区别,因为 var person
出现在 IIFE 的第一行。
如果它出现在 IIFE 中的任何其他行,那么它将被提升,相当于将它放在第一行。
通过 var
声明变量将始终使用 JavaScript 函数作用域。为了在全局范围内声明变量,您只需保留 var
定义即可。
var person = "your person" // function scope
person = "your person" // global scope
无论如何,您只是将同一个变量声明 两次。这基本上意味着您正在覆盖之前声明的 person
定义。这样做你最终会得到一个 undefined
变量,就像你在你的例子中看到的那样。
当您已经使用局部变量的名称时,您不能使用person
来引用外层循环变量,它是shadowed。您可以传递一个参数
var person = people[i];
(function (person){
…
}(person));
或者根本不使用外部作用域person
:
(function (){
var person = people[i];
…
}());
<!DOCTYPE>
<html>
<head>
<link rel="stylesheet" href="styles.css"/>
<body>
<ul id="people-list"></ul>
<script src="app.js"/>
</body>
</head>
</html>
***app.js***
var people = ["alf","kay","jay","may"];
var list = document.getElementById("people-list");
for(var i =0; i< people.length; i++){
var person = people[i];
var element = document.createElement("li");
(function (){
var person = person;
element.innerText = person;
element.addEventListener("click",function(){
alert("You clicked on "+ person);
});
}());
list.appendChild(element);
}
为什么在全局作用域中创建的 "person" 变量没有在 IIFE 中被引用,因此产生了一个未定义的列表,然后变量名从(例如 var person 到 var person2 和后续IIFE 中警报的更改)使代码正常工作。
由于吊装var person = person
正好等同于
var person;
person = person;
您不能在外部范围内引用 person
变量。它完全被局部变量遮盖了,所以你把未定义的局部变量赋给它自己。
Why is the "person" variable created in the Global Scope not being referenced in the IIFE
因为您在 IIFE 的范围内有一个 person
变量,它掩盖了它。
如果你有两个同名的变量,在不同的范围内,你只能访问在最近的范围内声明的那个。
提升在这里没有区别,因为 var person
出现在 IIFE 的第一行。
如果它出现在 IIFE 中的任何其他行,那么它将被提升,相当于将它放在第一行。
通过 var
声明变量将始终使用 JavaScript 函数作用域。为了在全局范围内声明变量,您只需保留 var
定义即可。
var person = "your person" // function scope
person = "your person" // global scope
无论如何,您只是将同一个变量声明 两次。这基本上意味着您正在覆盖之前声明的 person
定义。这样做你最终会得到一个 undefined
变量,就像你在你的例子中看到的那样。
当您已经使用局部变量的名称时,您不能使用person
来引用外层循环变量,它是shadowed。您可以传递一个参数
var person = people[i];
(function (person){
…
}(person));
或者根本不使用外部作用域person
:
(function (){
var person = people[i];
…
}());