Javascript 嵌套函数与吹走全局变量

Javascript 嵌套函数与吹走全局变量,javascript,Javascript,有些事情我需要理解,我必须帮助传达我的问题 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 v

有些事情我需要理解,我必须帮助传达我的问题

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:




如果您运行该plunk并点击顶部按钮,它将显示名称“Steve”。没什么难的。当你点击下面的按钮时,它会显示文本“Alan现在在这里。其他的名字已经被吹走了。”我想我明白了。基本上,room1中的nestedFunction是一个函数而不是方法。因为它不是任何对象的成员的方法,所以它位于全局命名空间中,并将person变量吹走(因此,this关键字不包含对room1对象的引用)

这是我不太明白的第三个按钮。如果刷新页面并单击第3个按钮,您将看到该变量不会将全局命名空间中的person变量吹走。在这种情况下,this关键字确实包含对room1对象的引用


我的问题是,命名函数(不是作为函数表达式创建的)是什么使它成为room2对象的成员,尽管它是嵌套的?或者甚至只是为什么它不吹走全局变量

这是因为room2中的nestedFunction定义和
(名称)
是两个独立的语句

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);
function nestedFunction(name) {
    this.person = name + ' name has been blown away';
} // end of function declaration
(name); // an expression statement which doesn't do anything
它创建一个函数,然后计算变量

要在Javascript控制台中演示:

function nestedFunction(name) {
     console.log("called")
}("example")
// "example"

room1
中,有一个函数表达式可以立即执行(也称为)。您是对的,
引用全局对象。因此

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';
};(name);
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

Ahhh中的行为完全相同。这是有道理的。谢谢你解释得很好的答案。有趣的是当我把声明的函数“nestedFunction”放在括号中时会发生什么。它将其全部解释为1条语句,自调用函数并将全局变量吹走。是的,因为分组运算符(
(…)
)只能包含表达式,所以函数定义被解释为(命名的)函数表达式,就像第一个示例中一样。谢谢。这是有道理的。在那美妙的语言中有如此多的细微差别。我喜欢!这实际上不是自动插入分号的情况。函数声明后从来没有分号,因此解析器不会在那里插入分号。更多信息:。@FelixKling噢,谢谢你指出这一点。因此,它不尝试将undefined作为函数调用的原因是因为语句终止时不需要分号?