代码之家  ›  专栏  ›  技术社区  ›  T. Stone

在JS中有正确的'this'值

  •  2
  • T. Stone  · 技术社区  · 14 年前

    我有两个类似的Javascript“对象”。。。。

    var Object2 = new (function() {
        this.FetchData = function(callback) {
            // do some stuff
            callback(data);
        };
    });
    
    var Object1 = new (function() {
    
        this.DisplayStuff = function() {
    
        };
    
        this.LoadData = function() {
            Object2.FetchData(this.OnData);
        };
    
        this.OnData = function(data) {
            // this == window
            this.DisplayStuff();   // doesn't work
        };
    
    });
    

    当Object1接收到对OnData的回调时,“this”的值设置为window。 有没有什么方法可以绕过这个问题,使OnData中的“this”值成为Object1的实例

    5 回复  |  直到 14 年前
        1
  •  3
  •   Andy E    14 年前

    简单的方法是存储对的引用 在变量中,然后使用 call() 方法:

    this.LoadData = function() {
        var self = this;
        Object2.FetchData(function () { self.OnData.call(self) });
    };
    

    如果您经常这样做,您可能需要考虑使用 .bind() 方法的函数原型。在以下不受支持的情况下可以实现此方法:

    // From Prototype.js
    if (!Function.prototype.bind) { // check if native implementation available
      Function.prototype.bind = function(){ 
        var fn = this, args = Array.prototype.slice.call(arguments),
            object = args.shift(); 
        return function(){ 
          return fn.apply(object, 
            args.concat(Array.prototype.slice.call(arguments))); 
        }; 
      };
    }
    

    以及生成的函数调用:

    this.LoadData = function() {
        Object2.FetchData(this.OnData.bind(this));
    };
    

    PrototypeJS - bind()

        2
  •  5
  •   Anurag    14 年前

    框架中常用的一种技术是让调用者决定 this 上下文应该是回调函数的上下文。所以 FetchData 函数看起来像(感谢@Andy告诉我上下文为null或未定义时的默认范围-它是全局对象),

    this.FetchData = function(callback, context) {
        callback.call(context, data);
    };
    

    打电话的时候 获取数据 ,通过 Object1 作为回调的上下文,

    Object2.FetchData(this.OnData, this);
    

    另一种选择是绑定 OnData 目标1 使用 Function.prototype.bind

    Object2.FetchData(this.onData.bind(this));
    
        3
  •  0
  •   Alex Mcp    14 年前

    apply . (或 call . 不同之处在于参数的传递方式。数组或“正常”)请参见 MDC

        4
  •  0
  •   Anthony -GISCOE-    14 年前

    对于回调,你会被“this”作为窗口(通常)。但是,您可以向Object1添加一个指向自身的成员(很多时候它被称为“self”,即“var self=this;”),然后使用它,即。自我展示().

        5
  •  0
  •   morgancodes    14 年前

    var Object2 = (function() { // no need for a "new" keyword any more
    
        var self = {}; // instead of the auto-supplied "this", create my own "self"
    
        self.FetchData = function(callback) {
            // do some stuff
            callback(data);
        };
        return self; // don't forget to return "self"
    });
    
    var Object1 = (function() {
    
        var self = {}; // instead of the auto-supplied "this", create my own "self"
    
        self.DisplayStuff = function() {
    
        };
    
        self.LoadData = function() {
            Object2.FetchData(this.OnData);
        };
    
        self.OnData = function(data) {
            self.DisplayStuff();
        };
    
        return self; // don't forget to return "self"
    
    });
    

    你失去了使用的能力对象.原型使用这种技术,您将失去使用“instanceof”进行测试的能力,但您永远不必考虑“this”是什么。