首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 网站开发 > JavaScript >

怎么创建一个JavaScript裸对象

2012-11-22 
如何创建一个JavaScript裸对象所谓裸对象,即 naked object ,是指没有原型(spec中以[[proto]]内建属性表示)

如何创建一个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}


不过这个技巧确实相当浪费,仅仅为了创建一个对象就建立了一整个iframe及其环境!那可相当于一个完整的网页!在IE中创建几千个这样的对象,就需要好几秒时间和几十兆内存!所以这个技巧只能用于真正需要的地方,比如with。虽然同样可以用于模拟Object.create(null)的行为,但是是否真的有这样的需求?或许更简单的方式是把一个普通对象上从Object.prototype继承来的属性遮蔽掉(即设为undefined),尽管这对于with来说不适合(原因请读者自己想),但是对于其他大多数情况可能就够用了。因此,我也不打算把这个trick提交给es5-shim项目,而只是仅用到我自己的一个项目中:my.js。

以上。



1 楼 myst729 2012-08-27   贺老你应该果断放弃对旧浏览器的支持…… 2 楼 p2227 2012-08-27   不用with就行了啊 3 楼 hax 2012-08-27   myst729 写道贺老你应该果断放弃对旧浏览器的支持……

在中国,面向大众的Web产品仍然要支持IE6,因为份额仍然在20%到30%左右。是否支持老浏览器,这是一个商业决策,不是技术决策。我个人估计跌到2%以下时(随便估计下还要3年左右吧)可以考虑放弃支持。不过还有IE8呢。这个就慢了。 4 楼 hax 2012-08-27   p2227 写道不用with就行了啊

99.9%的场合确实不应该用with,我的演讲里也是这样说的。但是确实有0.1%的场合可能要用。就是元编程,比如做模块系统。 5 楼 zhuzhuaijq 2012-10-25   var o = Object.create(null);

o.__proto__ === null

热点排行