2

有些事情我需要了解,我已经完成了一些工作以帮助传达我的问题。

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 中的nestedFunction是一个函数而不是方法。因为它不是任何对象的成员的方法,所以它位于 Global 命名空间中,它会清除person变量(因此,this关键字不包含对room1的引用对象的引用)。

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

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

4

2 回答 2

3

这是因为 nestedFunction 定义和(name)在 room2 中是两个独立的语句。

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"
于 2013-09-05T07:02:11.237 回答
2

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.

于 2013-09-05T07:02:20.400 回答