【问题标题】:How can I reference an object inside one of its member functions?如何在其成员函数之一中引用对象?
【发布时间】:2023-04-08 17:50:02
【问题描述】:

我有以下几点:

var o = {f: function(fn) {
    fn.call(o);
}};
var ob = {f: function() {
    o.f(function() {
        this.x = 2; //HERE: how can this reference ob?
        //ob.x = 2;
    });
}};
ob.f();
ob.x; // undefined

o.f(fn) 调用 fn,其中 this 绑定到 o。

在这里,我想使用this 访问ob。 但是,当调用ob.f 时,this 将绑定到o。 我认为 JQuery 是这样工作的。 例如:

$(...).blah(function() {
    this // this is bound to $(...) jquery object.
    ...
};

我现在做的是:

var Ob = function() {
    var self = this;
    self.f = function() {
        o.f(function() { self.x = 2; };
    };
};
var ob = new Ob();
ob.f();
ob.x; // 2

但出于文体原因,我不喜欢上述内容:

  1. 使用 new 运算符听起来太经典的 OOP。
  2. 使用function 定义<strong>class</strong> Ob 并不直观(至少在开始时是这样)。

这就是为什么我试图用一个对象字面量来定义ob。 但我找不到在函数中引用对象ob 的方法 使用将this 设置为ob 之外的其他对象的方法调用。

我可以执行以下操作:

var ob = {f: function() {
    o.f(function() {
        self.x = 2;
    });
}};
var self = ob;
ob.f();
ob.x;

但我不知道如何考虑以上因素。 我试过了:

function obj(o) {
    return function() {
        var self = o;
        return o;
    }();
}
var ob = obj({f: function() {
    o.f(function() {
        self.x = 2;
    });
}});
ob.f();
ob.x;// ReferenceError: self is not defined

那么,有没有办法在对象内部的函数中引用对象 可靠(this 可以根据上下文绑定到任何东西)?

【问题讨论】:

    标签: javascript oop this


    【解决方案1】:

    在 JavaScript 中,函数是对象,有两种调用函数的方法:

    call(scope, arg1, arg2, ...);
    apply(scope, args);  // args is an array of arguments to call the function with
    

    第一个参数“作用域”是函数内绑定到“this”的对象。所以,下面的例子是等价的:

    obj.method(1, 2, 3);
    obj.method.call(obj, 1, 2, 3);
    obj.method.apply(obj, [1, 2, 3]);
    

    在您的第一个示例中,您使用 'o' 作为范围调用传递给 o.f() 的函数:

    var o = {f: function(fn) {
        fn.call(o);
    }};
    

    因此,您的函数传入 'ob' 引用 'o' 如下:

    var ob = {f: function() {
        o.f(function() {
            this.x = 2; //HERE: how can this reference ob?
            //ob.x = 2;
        });
    }};
    

    在“HERE”行中,“this”实际上是“o”。

    您可以尝试以下方法:

    var ob = {f: function() {
        var self = this;
        o.f(function() {
            self.x = 2; // self is ob now
        });
    }};
    

    或者您可以修改函数 'o.f' 以获取范围参数:

    var o = {f: function(fn, scope) {
        fn.call(scope || this); // Uses the given scope or this (= 'o') if no scope is provided
    }};
    

    那么你可以在'ob'中传递'this':

    var ob = {f: function() {
        o.f(function() {
            this.x = 2; // 'this' will be the 'outer' this
        }, this); // Here: this as scope
    }};
    

    【讨论】:

    • 我试图用 o 模拟 jquery 对象的行为。正如我在 jquery 中所指出的,即使在我的对象中定义函数时,this 也会设置为 jquery 对象本身。我喜欢 Magnar 发布的 Douglas Crockfords 简单构造函数模式。
    【解决方案2】:

    遵循 Douglas Crockford 的简单构造函数模式,我将创建一个使用对象字面量而不是 new 的构造函数。像这样:

    var o = {f: function(fn) {
        fn.call(o);
    }};
    
    function obj() {
        var me = {};
        me.f = function () {
            o.f(function() {
                me.x = 2;
            });
        };
        return me;
    }
    
    var ob = obj();
    ob.f();
    ob.x; // 2
    

    【讨论】:

    • 'self' 已经是一个全局变量,如 'undefined' 和 'NaN'。请使用其他名称以减少混淆。
    【解决方案3】:

    你可以不用辅助函数,只用字面量:

    var o = {f: function(fn) {
        fn.call(o);
    }};
    var ob = {f: function() {
        var self = this; // this == ob
        o.f(function() {
            self.x = 2; // self == enclosing function's this == ob
        });
    }};
    ob.f();
    assert(ob.x == 2);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-11-24
      • 2020-08-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-12-20
      相关资源
      最近更新 更多