JS作用域中对象文字中的未定义变量

Undefined variable in the JS Scope in a object literal

本文关键字:未定义 变量 对象 作用域 JS 文字      更新时间:2023-09-26

我有以下代码(http://jsbin.com/disofaji/1/):

var test = {
  person: "nick",
  init: function() {
    $('#foo').click(function() {
      // how to access the person? 
      console.log(this.person);
    });
  },
};
test.init();

问题是,我得到了输出undefined,我想知道如何在我的点击处理程序中访问person

注意:点击处理程序只是我的问题的一个例子,我也有它在其他上下文中

这是因为在点击处理程序中,This实际上指的是触发事件的控件。

我已经更新了你的代码,它工作了。以下是你需要做的

var test = {
  person: "nick",
  init: function() {
    var obj = this;
    $('#foo').click(function() {
      // how to access the person? 
      alert("inside");
      console.log(obj.person);
    });
  },
};

test.init();

有一个众所周知的"技巧"来保留对函数原始作用域的引用:

init: function() {
  var self = this;
  $( '#foo' ).click( function() {
    console.log( self.person );
  } );
},

基本上,您需要将this变量"缓存"到另一个变量中(在本例中称为self)。然后,在单击处理程序内部,您可以访问self变量,就像它是单击处理程序外部的this变量一样。


另一个选择是简单地使用骨干的事件委托:

var test = {
  events: {
    "click #foo": "foo_click_handler"
  }
  person: "nick",
  foo_click_handler: function() {
      // callback is bound to the view scope, so "this" can be used normally.
      console.log( this.person );
  },
};

From the docs:

所有附加的回调在交给jQuery之前都绑定到视图,所以当回调被调用时,this继续引用视图对象。

代替使用var self = this; ie。保存对对象或其他事件库的引用,我会使用bind()(包含在JavaScript标准库中),这将使您的代码更简洁,更模块化。

bind所做的是将函数logperson绑定到你传递给它的对象上,在我们的例子中是this

这确实使您不必使用匿名函数,但就我个人而言,匿名函数总是更好的。

var logperson = function() {
    console.log(this.person);
};
var test = {
    person: "nick",
    init: function() {
        $('#foo').click(logperson.bind(this));
    };
 };