嵌套函数和吹走全局变量
Nested Functions and Blowing away Global Variable
有些事情我需要理解,我已经做了一个扑通来帮助传达我的问题。
JavaScript:
// "person" written as a plain object
var person = {
showName: function () { return this.name; },
setName: function (newName) { this.name = newName; }
};
// room is class where nested function is a lambda
var room1 = {
capacity: 10,
exits: 2,
count: 0,
person: 'this property is a String, not an Object',
addPerson: function (name) {
this.count += 1;
this.person = name;
var nestedFunction = function (name) {
this.person = name + ' name has been blown away';
}(name);
}
};
// room is class where nested function is a method
var room2 = {
capacity: 10,
exits: 2,
count: 0,
person: 'this property is a String, not an Object',
addPerson: function (name) {
this.count += 1;
this.person = name;
function nestedFunction(name) {
this.person = name + ' name has been blown away';
}(name);
}
};
.HTML:
<input id="PersonObjectButton" type="submit" value="Click Me First to See Person showName Method Called"
onclick="person.setName('Dave');alert(person.showName());" /> <br />
<input id="PersonObjectButtonAwry" type="submit" value="Click Me To Blow Away Global Variable"
onclick="room1.addPerson('Alan');alert(person);" /> <br />
<input id="PersonObjectButtonFine" type="submit" value="Click Me to See Person showName Method Called"
onclick="room2.addPerson('Alan');alert(person.showName());" /> <br />
如果您运行该 plunk 并点击顶部按钮,它会显示名称"Steve"。那里没什么难的。当您单击下面的按钮时,它会显示文本"艾伦现在在这里。另一个名字被吹走了。我想我明白这一点。基本上,room1 中的嵌套函数是一个函数而不是方法。因为它不是任何对象的成员的方法,所以它位于 Global 命名空间中,它会吹走 person 变量(因此,this 关键字不保存对 room1 对象的引用)。
这是我不太遵循的第三个按钮。如果刷新页面并单击第 3 个按钮,您将看到该变量不会吹走 Global 命名空间中的 person 变量。在这种情况下,this 关键字包含对 room1 对象的引用。
我的问题是,命名函数(不是作为函数表达式创建的)是什么使它成为 room2 对象的成员,尽管它是嵌套的?甚至只是为什么它不吹走全局变量?
这是因为 room2 中的 nestedFunction 定义和(name)
是两个单独的语句。
var nestedFunction = function (name) {
this.person = name + ' name has been blown away';
}(name);
此代码将创建一个函数,使用 name 变量调用它,然后将返回值分配给 nestedFunction
。
function nestedFunction(name) {
this.person = name + ' name has been blown away';
}(name);
另一方面,此代码创建一个命名函数。该操作的返回值始终未定义,因此无法立即调用该函数。相反,它将被视为两个单独的语句:
function nestedFunction(name) {
this.person = name + ' name has been blown away';
};(name);
它创建一个函数,然后计算变量!
要在 Javascript 控制台中进行演示:
function nestedFunction(name) {
console.log("called")
}("example")
// "example"
在room1
中,你有一个立即执行的函数表达式(也称为IIFE)。你是对的,this
指的是全局对象。因此
var nestedFunction = function (name) {
this.person = name + ' name has been blown away';
}(name);
相当于
window.person = name + ' name has been blown away';
在第二种情况下,使用函数声明。即使看起来像,也不会执行该函数。代码实际上被解释为两个语句:
function nestedFunction(name) {
this.person = name + ' name has been blown away';
} // end of function declaration
(name); // an expression statement which doesn't do anything
它与
function nestedFunction(name) {
this.person = name + ' name has been blown away';
}
name;
或者只是
function nestedFunction(name) {
this.person = name + ' name has been blown away';
}
我的问题是,命名函数不是作为函数表达式创建的,尽管它是嵌套的,但它还是使它成为
room2
对象的成员,这是什么?
没什么,它不会成为room2
的属性值。
甚至只是为什么它不吹走全局变量?
因为函数永远不会执行。如果将nestedFunction();
放在声明之后,它的行为与room1
完全相同。
- 在javascript函数中设置全局变量
- 如何从onclick函数设置全局变量并将其传递给另一个JS文件
- 创建要在其他函数中使用的全局变量
- 函数中的innerHTML(全局变量?)
- 全局变量只能由第一个函数访问
- 匿名自执行js函数内部的全局变量在外部仍然可用
- 更改函数内部的全局变量而不调用它
- 如何制作全局javascript函数和变量
- 改进js代码以删除全局变量和函数
- 调用函数后如何重置全局变量
- 无法在函数中检索全局变量的值
- 将全局变量传递给自调用函数或“IIFE”的目的
- 保留 JQuery Vars 用于另一个函数(全局变量?)
- 如何在 ajax 调用后更改包装器 JavaScript 函数中的全局变量
- 删除两个函数使用的全局变量
- 如何将socket.on中函数的值保存为全局变量
- angular/javascript无法识别函数内部的全局变量
- Javascript测试存根全局变量函数
- 在JavaScript中添加一个全局变量/函数(特别是NativeScript)
- Javascript从本地向全局变量函数添加行