如何创建一个JavaScript裸对象
所谓裸对象,即 naked object ,是指没有原型(spec中以[[proto]]内建属性表示)的对象。
JavaScript是少见的采用原型继承的语言。访问一个对象的属性时,会首先看它自己的属性,所谓 own property 是也,如果找不到,则在其原型中查找,再找不到就继续找这个原型的原型,这就构成所谓的原型链。
原型继承提供了一种很独特的共享信息的方式,不过也带来一些有趣的问题。比如with构造。
我在2011年w3ctech广州的演讲中提到过with构造的问题,所以在strict模式中with就被禁用了。
其中一个问题是,with(obj)时,obj如果是你不可掌控的对象,会引入无法控制的风险。所谓不可掌控,例如浏览器对象(像在演讲中举的event对象),或者第三方库的对象或可能被第三方库修改的对象(例如DOM对象就是如此,许多库会在上面加各种东西)。
这和原型有什么关系?很有关系!因为with不是仅仅查找own property,而是也会上溯原型链。
例子:
function nakedObject() {var iframe = document.createElement('iframe')iframe.width = iframe.height = 0iframe.style.display = 'none'document.appendChild(iframe)iframe.src = 'javascript:'var proto = iframe.contentWindow.Object.prototypeiframe.parentNode.removeChild(iframe)iframe = nullvar props = ['constructor', 'hasOwnProperty', 'propertyIsEnumerable','isPrototypeOf', 'toLocaleString', 'toString', 'valueOf' ]for (var i = 0; i < props.length; i++) {delete proto[props[i]]}return proto}