如何保持';这';在javascript闭包中的类中

如何保持';这';在javascript闭包中的类中,javascript,closures,Javascript,Closures,我读过很多书,但似乎找不到解决问题的正确方法 我这里有一个简单的类: define(['jquery'], function($) { // Need 'self' because someCallback() is being called with .call() and 'this' changes var self; function Foo(number) { self = this; this.someNumber = num

我读过很多书,但似乎找不到解决问题的正确方法

我这里有一个简单的类:

define(['jquery'], function($) {
    // Need 'self' because someCallback() is being called with .call() and 'this' changes
    var self;

    function Foo(number) {
        self = this;
        this.someNumber = number;
    }

    Foo.prototype = {
        someCallback: function () {
            //Use self because 'this' changes to a DOM element
            var num = self.someNumber;

            //Do something with the num
            return num * 2;
        }
    };

    return Foo;
});
jQuery插件正在使用
.call()
调用
someCallBack()
。因此,上下文发生了变化,因此使用了
self
变量

然而,这是错误的,因为:

define(['foo'], function(Foo) {
    describe('context question', function () {
        var foo1 = new Foo(1);
        var foo2 = new Foo(2);

        it('"this" should work', function () {
            var call1 = foo1.someCallback.call(this); // 4
            var call2 = foo2.someCallback.call(this); // 4

            expect(call2).toBe(4); // Only works because it is 'new' last
            expect(call1).toBe(2); // Fails because 'self' is taken from foo2
        });
    });
});

我应该如何包装
self
变量才能使代码正常工作

您可能只需使用并将其声明为“全局”变量(模块的局部变量):


调用存储其自身此值的对象方法的两种方法包括

  • 将该方法定义为嵌套函数,该函数在闭包中引用其this值,闭包将
    this
    值存储在变量中。定义的函数可以是匿名的,也可以用名称声明,但必须在每次创建类实例时进行计算,以便创建一个新的函数对象,该对象在函数范围中捕获不同的
    self

  • 获取静态定义的函数对象,并使用
    bind
    将其绑定到此值。每次调用时创建一个新的包装函数对象

  • 第一个方法看起来像(没有Jquery或Jasmine):

    第二种方法可能看起来像

    function Foo(number)
    {   this.num = number
        this.someCallback = this.someCallback.bind(this); // bind prototypical method as local method.
    }
    
    Foo.prototype = {
        someCallback: function () {
            // this value is bound by constructor;
            //Do something with the num
            return this.num * 2;
        }
    };
    

    我试过这个代码,但不起作用。问题是,在我调用
    newfoo(2)
    后,
    someNumber
    将发生变化。谢谢。我尝试了第二种方法,但不起作用。我认为
    .call()
    正在改变
    这一点。第一种方法非常有效。然而,这是一件“适当”的事情吗?据我所知,这将为每个
    Foo
    一次又一次地重新创建
    someCallback()
    。这是常见的吗?(很抱歉,在JS中创建对象仍然是一种新方法)如果复制并粘贴第二个方法,由于“someCallback”中的“Back”的上半部大写,所以它会失败,而它应该是小写的。我已经更新了第二个代码示例-您能确认它是否仍然失败吗?即使如此,在对象构造函数中创建新函数对象还是很常见的,尽管有时可能是由于编程风格而非必要性;-)
    function Foo(number)
    {   var self = this;
        this.num = number;
        this.someCallback = function()  // method with new Foo object stored as self in function scope 
        {   // something with num:
            return self.num * 2;
        }
    }
    
    function Foo(number)
    {   this.num = number
        this.someCallback = this.someCallback.bind(this); // bind prototypical method as local method.
    }
    
    Foo.prototype = {
        someCallback: function () {
            // this value is bound by constructor;
            //Do something with the num
            return this.num * 2;
        }
    };