【问题标题】:Javascript scope and variablesJavascript 范围和变量
【发布时间】:2014-02-17 13:18:40
【问题描述】:
var name = "Bob";

var book = {
    name: "Harry Potter",
    writeName: function() {
        return function() {
            document.writeln(this.book.name);
        }
    }
};

当我调用它时

book.writeName()();

我希望它打印上面的 Harry Potter(不是 Bob),但是:

var book2 = book;
book = null;
book2.writeName()();

现在寻找this.book(即null)它应该在哪里寻找this.book2

如何引用变量?

【问题讨论】:

  • 不要使用this
  • @Bergi 但是当我更改为 book2 时,它仍然在寻找 book
  • 好的,抱歉,我必须细化:不要在不合适的地方使用this,就像这里在返回的函数中this 指的是全局对象:-)

标签: javascript variables scope


【解决方案1】:

你需要的是writeName闭包中的一个变量:

var book = {
    name: "Harry Potter",
    writeName: function() {
        var name = this.name; // turn dynamic property into closure variable
        return function() {
            document.writeln(name);
        }
    }
};
book.writeName()(); // Harry Potter

除了在闭包中仅存储 name 之外,您还可以存储对对象的引用,就像在 @Quentin 的回答中一样。如果您计划在调用返回的函数之前更改 .name 属性,这可能会有所不同。

关于是否使用thisbook 来引用您的对象的问题,请参阅Javascript: Object Literal reference in own key's function instead of 'this'

【讨论】:

    【解决方案2】:

    由于您要返回一个函数,因此您将失去从调用生成它的函数中获得的任何上下文。

    您需要该上下文来引用该对象,因此您需要保留它。

    writeName: function() {
        var myBook = this;
    

    然后您需要使用保留的上下文:

        return function() {
            document.writeln(myBook.name);
        }
    

    【讨论】:

      【解决方案3】:

      试试这个:http://jsbin.com/pagumiwi/4/edit

      var name = "Bob";
      
      var book = {
          name: "Harry Potter",
          writeName: function() {
              return function() {
                  document.writeln(this.name);
              }
            }()
          };
      
      
      
      book.writeName(); //would also work
      var book2 = book;
      book = null;
      book2.writeName(); //would also work
      

      【讨论】:

      • @RoyiNamir 我不想改变调用函数的方式,所以我仍然想调用 book.writeName()();
      • @CamSonaris 你应该在你的问题中提到这一点。
      【解决方案4】:

      因为this 会在上下文发生变化时发生变化,所以您需要保存对原始this 的引用。这里我使用了_this

      var book = {
        name: "Harry Potter",
        writeName: function() {
          var _this = this;
          return function() {
            console.log(_this.name);
          }
        }
      };
      
      book.writeName()() //  Harry Potter
      
      var book2 = book;
      book = null;
      book2.writeName()();  //  Harry Potter
      

      Demo

      【讨论】:

        猜你喜欢
        • 2010-12-21
        • 2015-07-28
        • 2020-02-07
        • 2012-12-23
        • 2011-05-10
        • 2011-07-07
        相关资源
        最近更新 更多