【问题标题】:JavaScript closure, about object and thisJavaScript 闭包,关于对象和 this
【发布时间】:2014-12-07 06:27:44
【问题描述】:
function abc(v){
    console.log(v);
}

var abcd= abc;

var module = {
    name: "hello",
    innerFunc: function(){
        console.log("name "+name);

    },
    outterFunc: abc("run from module")
}

有没有办法在innerFunc 中引用name 的值?

我的想法是应该有办法,因为它们都在 module 对象中。我可能完全错了。

请告诉我为什么,为什么不呢?

PS:

其实我是通过添加以下代码想出来的

var module = {
    name: "hello",
    innerFunc: function(){
        var self = this;
        console.log("name "+self.name);
    },
    outterFunc: abc("run from module")
}

那么,接下来的问题是,为什么innerFunc 不像outterFunc 那样运行,outterFunc 在运行代码后立即被调用,为什么innerFunc 必须显式调用为module.innerFunc() .

谢谢

【问题讨论】:

  • 因为您正在调用abc("run from module") 并将其返回值分配给outterFunc(拼写“outer”是错误的),而对于innerFunc,您只是将函数表达式分配给属性没有调用它。因此,您可以在之后使用module.innerFunc 调用它。您是否对一流的功能感到困惑?

标签: javascript closures


【解决方案1】:

首先,您不必将this 别名为self 即可使用实例属性。你可以像这样写innerFunc

innerFunc: function(){
    console.log("name "+this.name);
},

您可能在其他代码示例中看到过var self = this,这是一种常见的方法来解决this 在您进入函数范围时会发生变化的事实。这不是我关心的技术……使用有意义的变量名通常更清楚。但是,在您的情况下,根本不需要将 this 别名为 self

要回答您的第二个问题,了解函数定义和函数调用之间的区别很重要。

当您定义一个函数时,它不会被执行——无论它是在哪里定义的。考虑以下示例:

function f() {
    console.log('f');
}
var o = {
    m: function() {
        console.log('m');
    }
}

在该示例中,有两个函数定义,但没有函数调用。换句话说,如果你运行这个脚本,函数f会存在,方法o.m也会存在,但都不会被执行,所以命令行上不会打印任何内容。一般来说,如果您看到关键字function,您处理的是函数定义,不是调用。下面的代码现在依次调用这两个函数:

f();
o.m();

在这种情况下,将发生对console.log 的两次调用。

在您的示例中,您通过调用函数abc(我怀疑这不是您想要做的)来定义属性outerFunc。我怎么知道你在调用它?因为有括号,没有function关键字:

var module = {
    //...
    outterFunc: abc("run from module")
}

这里发生的事情是abc调用 并且它的返回值 被分配给outerFunc。由于abc 不返回任何内容,outerFunc 将获得值undefined。这就是为什么我猜这不是你想要的。如果您希望m.outerFunc 成为abc别名,您可以这样做:

var module = {
    //...
    outerFunc: abc
}

注意没有括号...所以abc调用。现在module.outerFuncabc 的别名。不过要小心!这是在 JavaScript 中给函数取别名的一种危险方式……在这种情况下,这可能没问题,因为您正在为函数(而不是方法)取别名,因此 this 不是您所期望的那样几乎没有危险,但是您如果您尝试将方法彼此别名,则会遇到这种情况。所以总的来说,这种技术应该谨慎使用。

如果你想让outerFunc呼叫abc,你必须这样做:

var module = {
    //...
    outerFunc: function() {
        abc();
    }
}

在这种情况下,abc没有被调用...它在函数定义中,所以它只会在m.outerFunc被调用时被调用。

我知道这一切起初看起来都很令人困惑,但这些都是非常重要的区别,所以如果这个答案不清楚,请告诉我。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-09-25
    • 1970-01-01
    • 2010-10-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-10-11
    • 1970-01-01
    相关资源
    最近更新 更多