有没有办法防止在单例实例中覆盖/覆盖函数/变量?

poc*_*sar 16 javascript singleton overwrite javascript-objects

考虑这个伪代码:

(function(window){
   var options = { /*where everything goes */ };

   var instance = (function(options){
       for (var i in options){
       if (options.hasOwnProperty(i)){
         this[i] = options[i];
       }
     }
   })(options);

   instance.callbacks = function(cb){
     //...
   }

   instance.is_allowed = function()
    //... checks, return boolean
   }

   window.instance = instance;
})(this);
Run Code Online (Sandbox Code Playgroud)

如果有人想操纵这个代码(例如恶意用户),他会is_allowed用自己的代码重写函数,例如,使用地址栏(他没有萤火虫,谁知道).

javascript:(function(){ window.instance.is_allowed = function(){ return true; } })();
Run Code Online (Sandbox Code Playgroud)

这是一个简单的例子,但重点是,Javascript中的任何内容都可以被覆盖.

我知道在es5中我们有Object.defineProperty,所​​以你可以设置:

// being explicit
Object.defineProperty(instance, "is_allowed", {
  enumerable: false,
  configurable: false,
  writable: false,
  value: function(){
    // do checks
  }    
});
Run Code Online (Sandbox Code Playgroud)

实际上,在这个意义上最好的是使用Object.freeze(instance)Object.seal(instance)代替Object.defineProperty,因为后者可以再次调用writable: false(傻呀?)

是否有任何方式可以在旧浏览器(即IE6-8)中工作而不会有太多麻烦?如果这是不可能的,那么我只会耸耸肩继续前进.

Fag*_*ack 2

如果有人想要操纵此代码(例如恶意用户),他会用自己的代码重写 is_allowed 函数

他可以重写你的整个 JavaScript 代码,或者甚至不使用浏览器,而是模拟向你的服务器发出“无浏览器”请求。

有没有什么方法可以让它在旧浏览器(即 IE6-8)中工作而没有太多麻烦?

不。您在全局公开的任何内容都可以由用户更改,这取决于浏览器限制该行​​为,javascript:以避免用户被欺骗访问预先制作的链接。Firefox 最近对 javascript URL 协议进行了某种更改。

正如本文所述:http://survey-remover.com/blog/javascript-protocol-dangers/

从 Chrome v13、Firefox v6 和 IE 9 开始,浏览器开发人员已经注意到“javascript:”协议的危险,并随后禁止了代码...在 Chrome 和 IE 中,“javascript:”子字符串是粘贴代码时会被删除,而 Firefox 不再在活动页面的范围内执行脚本。

所以...

如果这是不可能的,那么我只会耸耸肩,继续前进。

你应该。