论坛首页 Web前端技术论坛

无污染的 JavaScript 对象设计

浏览 9353 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2008-07-12  

在使用JavaScript构建对象时,出于某种需求要使用prototype(原型定义)设计,

不过这种设计当中有一个讨厌的事情就是Array污染,比如这样定义:

Array.prototype.foo='foo';

 这是一个典型的Array污染,因为所有的Array对象都会继承foo这个成员。这对于习惯用

for (var in [])

这样语法的是个灾难,虽然有方法可以避免,但是这个问题的麻烦还有很多。

现在介绍一种无污染的设计方法:

function array(){};
array.prototype=[];
array.prototype.slice=function(){return this.length;}
var a=new array;
alert('array.slice():'+a.slice());
alert('Array.slice():'+[1,2,3].slice(1));
function object(){};
object.prototype={};
object.prototype.foo=function(){return this.name;}
var o=new object;
o.name='name from new object';
alert('object.foo():'+o.foo());
alert('{foo:"foo"}.foo:'+({foo:"foo"}).foo);

就是这样了,如果你的代码有一些特殊的需要,也许这个方法会有所帮助。

   发表时间:2008-07-13  
array的length不正确
0 请登录后投票
   发表时间:2008-07-13  
其实,要解决这个问题,如果你不嫌麻烦,可以在同一个页面上生成一个隐藏的iframe,然后,扩展这个iframe里面的Array对象,并使用它来生产你要的数组实例,这样就能保证你父页面的原型纯净……

但是,就我看来,for..in语句本来就不是专门设计供迭代数组的,而是列举对象可迭代成员的语法,所以,Prototype的设计也是合理的,当然,这是个人观点,其实也是Prototype的设计哲学之一。
0 请登录后投票
   发表时间:2008-07-14  
csf178 写道
array的length不正确

我的例子程序是故意写一个错误的slice的.
0 请登录后投票
   发表时间:2008-07-14  
笨笨狗 写道
其实,要解决这个问题,如果你不嫌麻烦,可以在同一个页面上生成一个隐藏的iframe,然后,扩展这个iframe里面的Array对象,并使用它来生产你要的数组实例,这样就能保证你父页面的原型纯净……

但是,就我看来,for..in语句本来就不是专门设计供迭代数组的,而是列举对象可迭代成员的语法,所以,Prototype的设计也是合理的,当然,这是个人观点,其实也是Prototype的设计哲学之一。

我的意思是不必对Array,Object的prototype动手,也可以实现类似的prototype,
一般情况下我们常见的构造函数都是生成一个Object实例,我这个方法可以生成Array实例,当然这是javascript本来就支持的,用protorype来生成Array的方法很少见(其实是我从来没有见过),当我发现可以这样写的时候就发了这个帖子,
0 请登录后投票
   发表时间:2008-07-14  
笨笨狗 写道
其实,要解决这个问题,如果你不嫌麻烦,可以在同一个页面上生成一个隐藏的iframe,然后,扩展这个iframe里面的Array对象,并使用它来生产你要的数组实例,这样就能保证你父页面的原型纯净……

但是,就我看来,for..in语句本来就不是专门设计供迭代数组的,而是列举对象可迭代成员的语法,所以,Prototype的设计也是合理的,当然,这是个人观点,其实也是Prototype的设计哲学之一。

这个其实是不允许的 你可以try一下
0 请登录后投票
   发表时间:2008-07-14  
achun 写道
csf178 写道
array的length不正确

我的例子程序是故意写一个错误的slice的.

不是 你这样做其实跟
array.prototype=new Array没什么两样
在IE中 array的实例没法作为真正的数组使用

Function更是如此
0 请登录后投票
   发表时间:2008-07-14  
achun 写道
笨笨狗 写道
其实,要解决这个问题,如果你不嫌麻烦,可以在同一个页面上生成一个隐藏的iframe,然后,扩展这个iframe里面的Array对象,并使用它来生产你要的数组实例,这样就能保证你父页面的原型纯净……

但是,就我看来,for..in语句本来就不是专门设计供迭代数组的,而是列举对象可迭代成员的语法,所以,Prototype的设计也是合理的,当然,这是个人观点,其实也是Prototype的设计哲学之一。

我的意思是不必对Array,Object的prototype动手,也可以实现类似的prototype,
一般情况下我们常见的构造函数都是生成一个Object实例,我这个方法可以生成Array实例,当然这是javascript本来就支持的,用protorype来生成Array的方法很少见(其实是我从来没有见过),当我发现可以这样写的时候就发了这个帖子,

正确的做法应该是实例继承(这名字是听人说的,其实从这种继承的行为来看也是一种原型继承)
function ArrayEx(){
    var instance=Array.apply(this,arguments);
    instance.myMethod=function(){/*...*/};
    instance.myProperty="any value";
    return instance;
}

像Array这种new与不new一个样的内置对象比较好办 Date的话就要稍微处理一下了
0 请登录后投票
   发表时间:2008-07-14  
for..in其实就是迭代器 可以针对任何集合使用的
JS1.8还可以改变默认行为迭代range呢
0 请登录后投票
   发表时间:2008-07-14  
csf178 写道
achun 写道
csf178 写道
array的length不正确

我的例子程序是故意写一个错误的slice的.

不是 你这样做其实跟
array.prototype=new Array没什么两样
在IE中 array的实例没法作为真正的数组使用

Function更是如此

还真是有兼容性问题,
看来目前的JavaScript 引擎规范化是个大问题呀!
我一直对用prototype来创建实例,只能创建Object类型感到郁闷,偶然在FF下发现可以创建Array类型(但是不能创建Function类型),就有了这个帖子.


呵呵,还是老老实实的 用实例扩展方法吧.
0 请登录后投票
论坛首页 Web前端技术版

跳转论坛:
Global site tag (gtag.js) - Google Analytics