与「」混淆;这";JavaScript匿名函数中的对象

与「」混淆;这";JavaScript匿名函数中的对象,javascript,scope,this,Javascript,Scope,This,嗨,我有下面的JavaScript代码,我正在尝试运行。我的目标是在JavaScript的不同范围和不同类型的调用中理解这个的含义 如果您查看下面的代码:我有一个内部匿名函数,它被分配给innerStuff变量。在类似于的匿名函数中,此指向窗口对象,而不是外部函数对象或任何其他对象。事件,尽管它仍然可以访问out函数的变量 无论如何,我不确定,为什么会这样;但如果您查看下面的代码,我稍后会将这个以那个的形式传递给innerStuff,它工作正常,并在控制台中打印带有doofus属性的对象

嗨,我有下面的JavaScript代码,我正在尝试运行。我的目标是在JavaScript的不同范围和不同类型的调用中理解
这个
的含义

如果您查看下面的代码:我有一个内部匿名函数,它被分配给
innerStuff
变量。在类似于
的匿名函数中,此
指向
窗口
对象,而不是外部函数对象或任何其他对象。事件,尽管它仍然可以访问out函数的变量

无论如何,我不确定,为什么会这样;但如果您查看下面的代码,我稍后会将
这个
那个
的形式传递给
innerStuff
,它工作正常,并在控制台中打印带有
doofus
属性的对象

    var someStuff = {
        doofus:"whatever",
        newF: function()
        {
            var that = this;
            console.log(that);
            var innerStuff = function(topThis){
                console.log(topThis);
            };

            return innerStuff(that);
        }
    }

    someStuff.newF();
现在我只修改了一点代码。我将不将其分配给
innerStuff
,而是通过调用它直接返回函数,如下所示:

    var someStuff = {
        doofus:"whatever",
        newF: function()
        {
            var that = this;
            console.log(that);
            return function(that){
                console.log(that);
            }();
        }
    }

    someStuff.newF();
这将打印内部匿名函数的未定义。是否因为作为参数传递的
和在外部函数中定义的
之间存在冲突?
我以为参数会覆盖可见性。为什么不保留该值

这完全令人困惑

另一方面,如果我没有传递
那个
,而是直接使用它,因为可见性在那里,结果是正确的,正如预期的那样

我错过了什么?是同一范围内变量之间的冲突吗?
内部函数将
绑定到
窗口
对象是否有充分的理由?

在JavaScript中指的是调用方法的对象。如果将函数调用为
someObject.functionName(args)
,则
将绑定到该对象。如果只调用一个裸函数,如
functionName(args)
,则
将绑定到
窗口
对象

在第二个示例中,在
newF
的内部,您在内部函数中隐藏了
变量,但没有向其传递任何内容,因此它是未定义的

        var that = this;
        console.log(that);
        return function(that){
            console.log(that);
        }();
如果您想要与第一个示例等效的内容(将
that
传递到内部函数),则可能需要以下内容:

或者,如果不想对其进行阴影处理,只需使用外部函数的绑定即可:

        var that = this;
        console.log(that);
        return function(){
            console.log(that);
        }();

在第二个示例中,当您调用匿名函数时,
的参数
没有定义(您没有向它传递任何内容)。您可以执行以下操作:

    newF: function()
    {
        var that = this;
        console.log(that);
        return function(that){
            console.log(that);
        }(that); // note that we are passing our 'that' in as 'that'
    }
这将保持变量的正确值

但是,由于您正在界定上述
var的范围,因此也可以删除函数参数:

    newF: function()
    {
        var that = this;
        console.log(that);
        return function(){
            console.log(that);
        }(); // 'that' is referenced above.
    }
至于为什么匿名函数将
窗口
作为其
:无论何时调用没有上下文的函数(即
somef()
vs
context.somef()
将指向
窗口
对象

您可以在函数上使用覆盖并传递
。例如:

    newF: function()
    {
        console.log('Outer:', this);
        var innerF = function(){
            console.log('Inner:', this);
        };
        return innerF.apply(this,arguments);
    }

在第一个代码示例中,匿名函数虽然在
someStuff
对象的成员函数中声明,但不是
someStuff
对象的成员。因此,
该函数中的该
是对窗口对象的引用。如果要调用匿名函数并控制
引用,可以执行以下操作:

var someStuff = {
    doofus:"whatever",
    newF: function()
    {
        var that = this;
        console.log(that);
        var innerStuff = function(){
            console.log(this);
        };

        return innerStuff.apply(this);
    }
}

someStuff.newF();
在第二个示例中,您实际创建了一个匿名函数,执行它,然后返回匿名函数返回的值。但是,匿名函数没有返回任何内容。此外,还存在变量名冲突。你可以做:

var someStuff = {
    doofus:"whatever",
    newF: function()
    {
        var that = this;
        console.log(that);
        return function(){
            console.log(that);
            return true;
        }();
    }
}

someStuff.newF();

我添加了return true,因为您的函数应该返回一些东西,因为执行它的函数正在返回匿名函数的返回值。它是否返回true或false、字符串或对象或其他任何内容取决于场景。

ah!!真不敢相信我错过了。非常感谢。好吧,这与其他语言中绑定方法的工作方式完全不同……我同意第一点,我可以使用“应用”调用,但第二点是不正确的。不存在名称冲突,因为传递的参数会覆盖外部函数中的参数。我犯的错误是在调用时没有将参数传递给匿名函数。[如上面例子中的Brian所示]他被纠正了,因为他建议的解决方案工作得很好。至于返回值;我不这么认为,我太在乎了;我只是想看看这个/那个的值在内部函数中的作用域。谢谢你的帮助。
var someStuff = {
    doofus:"whatever",
    newF: function()
    {
        var that = this;
        console.log(that);
        return function(){
            console.log(that);
            return true;
        }();
    }
}

someStuff.newF();