在嵌套的文字对象中绑定它

时间:2014-12-15 06:05:51

标签: javascript this bind object-literal

我们说我有这个代码

(function() {

    function Foo(arg) {
        this.name = arg;
    }

    Foo.prototype = {
        bar: {
            baz: function() {
                alert(this.name); // Undefined...
            }
        }
    }

    var foo = function(arg) {
        return new Foo(arg);
    };


    window.foo = foo;

    return foo;
}());

foo("Anything").bar.baz();

我如何制作"这个"在我的功能" baz"当我从外面调用它时,是指对象Foo而不使用bind或apply?

2 个答案:

答案 0 :(得分:2)

FWIW,我强烈建议构建这样的嵌套结构,或至少不在原型上,因为bar对象共享这些实例打开了通向交谈式错误的很多的大门。相反,我在构造函数中创建bar

  

我如何制作"这个"在我的功能" baz"当我从外面调用它时,是指对象Foo而不使用bind或apply?

您可能会对bindapply / call稍有疑惑。当调用函数时,你不会使用bind,但在创建它时。除非您使用bind(或与其相同的内容),否则您无法执行您想要的内容,因为缺少bind(或类似),this是根据函数的调用方式设置的,因此this.bar.baz()会使this成为调用中的this.bar

以下是如何在构造函数中构建bar,并使用bind使baz使用正确的this

function Foo(arg) {
    this.name = arg;
    this.bar = {
        baz: function() {
            alert(this.name);
        }.bind(this)            // <== Note
    };
}

示例:

&#13;
&#13;
function Foo(arg) {
  this.name = arg;
  this.bar = {
    baz: function() {
      snippet.log(this.name);
    }.bind(this)            // <== Note
  };
}

var f1 = new Foo("f1");
var f2 = new Foo("f2");
f1.bar.baz(); // "f1"
f2.bar.baz(); // "f2"
&#13;
<!-- Script provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 -->
<script src="http://tjcrowder.github.io/simple-snippets-console/snippet.js"></script>
&#13;
&#13;
&#13;


有关串扰的更多信息:天真的事情是只需在Foo构造函数中添加一行,并在原型上保留bar

this.bar.baz = this.bar.baz.bind(this);

这将是一个非常糟糕的主意,因为您会在实例之间进行串扰:

&#13;
&#13;
function Foo(arg) {
  this.name = arg;
  this.bar.baz = this.bar.baz.bind(this); // DON'T DO THIS
}

Foo.prototype = {
  bar: {
    baz: function() {
      snippet.log(this.name);
    }
  }
};

var f1 = new Foo("f1");
var f2 = new Foo("f2");
f2.bar.baz(); // "f1" -- cross talk! Should be f2
&#13;
<!-- Script provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 -->
<script src="http://tjcrowder.github.io/simple-snippets-console/snippet.js"></script>
&#13;
&#13;
&#13;

答案 1 :(得分:0)

在声明时使用bind来正确地确定范围,例如

function foo() {}.bind(this);