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

我有类似的东西:
var a = (function () {

    return {

        b: 1,c: function () {

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

所以,

a.c(); // = 1

但如果我这样做

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

是否可以在“a.c()”中保留“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的答案的解决方案,将return语句拆分为init(),因此在任何情况下对于对象上下文(和实例)都是安全的.

对于单身人士模式:

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;
})();

这应该具有相同的效果,但它确实消除了这种使用.

如果你不能改变这么多的结构,那么你可以(更多)更危险地使用:

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

如果你选择这个,虽然你必须警惕,任何时候使用a.c.apply它将不再“按预期”工作 – 它将解决这里提出的问题.

相关文章

前言 做过web项目开发的人对layer弹层组件肯定不陌生,作为l...
前言 前端表单校验是过滤无效数据、假数据、有毒数据的第一步...
前言 图片上传是web项目常见的需求,我基于之前的博客的代码...
前言 导出Excel文件这个功能,通常都是在后端实现返回前端一...
前言 众所周知,js是单线程的,从上往下,从左往右依次执行,...
前言 项目开发中,我们可能会碰到这样的需求:select标签,禁...