如何在单例模式中保存javascript“this”上下文?

我有类似的东西:

var a = (function () {

    return {

        b: 1,
        c: function () {

            console.log(this.b);
        }
    };
})();

所以,

a.c(); // = 1

但如果我这样做

b = 2;
a.c.apply(this); // = 2

是否可以在“ac()”内部保留“this”的上下文而不改变(太多)“a”对象的结构? 我没有控制函数的调用,所以我需要一个解决方法来处理这个对象本身。

更新

更具体地说,这是我的文件的结构:

结构1(单一样式):

var a = (function () {

    var _instance;

    function init() {

        return {

            b: 1,
            c: function () {

                console.log(this.b);
            }
        };
    }

    return {

        getInstance: function () {

            if (_instance === undefined) {
                _instance = init();
            }

            return _instance;
        }
    }
})();

结构2:

var b = {

    c: 1,
    d: function () {
        console.log(this.c);
    }
};

解答

我已经实现了一个基于Mahout的答案的解决方案,将init()中的return语句分开,因此在任何情况下它都可以保持对象上下文(和实例)的安全。

对于单身模式:

var a = (function () {

    var _instance,
        self;

    function init() {

        return self = {

            b: 1,
            c: function () {

                console.log(self.b);
            }
        };
    }

    return {

        getInstance: function () {

            if (_instance === undefined) {
                _instance = init();
            }

            return _instance;
        }
    };
})();

对于对象字面量:

var b = (function () {

    var self;

    return self = {
        c: 1,
        d: function () {
            console.log(self.c);
        }
    };
})();

所以

a.getInstance().c(); // 1
a.getInstance().c.apply(this); // 1
setTimeout(a.getInstance().c, 1); // 1
$.ajax({ complete: a.getInstance().c }); // 1

您可以稍微改变从匿名函数返回对象的方式:

var a = (function () {
   var result = {};
   result.b = 2;
   result.c = function() {
     console.log(result.b);
   };
   return result;
})();

这应该有同样的效果,但它的确取消使用this

如果你不能改变的结构a多这一点,那么您交替可以(多)更危险的使用方法:

a.c.apply = function() { // Stops the apply function working on a.c by overriding it
    return a.c();
}

如果你选择了这个,尽管你必须警惕任何时候使用acapply ,它将不会像预期的那样工作 - 它将解决这里提出的问题。


我用这支笔来说明差异,我希望这有助于:

http://codepen.io/dieggger/pen/BNgjBa?editors=001

var a = (function () {
    return { b: 1,
             c: function () {
              console.log(this.b);
            }
    };
})();


a.c(); //prints 1


b = 2; // global variable "b" which is being hoisted BTW


// The following will act like this:

//it throws "cannot read property 'apply' from undefined" 
//though it prints "1" since the first part invokes the "c" function 
//inside of the"a" module which has the console.log

a.c().apply(this); 


//In this case "this" is the window object which has the variable "b"
a.c.apply(this); // it'll print 2

你可以这样做:

var a = (function ()
{
    return {
        b: 1,
        c: function ()
        {
            console.log(this.b);
        }
    }
})();

var decorator = function() { return a; };

var b = 2;

decorator.call(this).c(); // => 1

基本上它看起来像你想绑定IIFE,而不是它返回的对象到外部范围,以便嵌套的返回对象保留内部的值b

链接地址: http://www.djcxy.com/p/28393.html

上一篇: How to preserve javascript "this" context inside singleton pattern?

下一篇: Why does Unix block size increase with bigger memory size?