`
achun
  • 浏览: 313690 次
  • 性别: Icon_minigender_1
  • 来自: 河南郑州
社区版块
存档分类
最新评论

无污染的 JavaScript 对象设计

阅读更多

在使用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);

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

分享到:
评论
22 楼 Relucent 2008-08-26  
indexOf之类的常用方法 还是喜欢直接在Array上追加。

另外 for (var in []) 遍历数组本来就有不少问题,for...in主要用于遍历简单对象的。(当作map用的那种)
21 楼 hax 2008-07-25  
几点:

1. Array、Function、RegExp等是不能被继承的,因为有些特性无法继承(比如内置的[[call]]、[[length]])。

2. Array的污染其实不是很大的问题,因为for in枚举一般是只用于object的,而且是被当作map使用的object。

3. 用Frame得到一个sandbox是个不错的trick,但是跨frame的js行为是存在不确定性的,特别是IE上。
20 楼 csf178 2008-07-16  
笨笨狗 写道
csf178 写道
以前try抛出来个安全异常
现在try了 结果是IE的Array2==Array为true
FF抛异常 麻烦try出来的同学贴个代码看看

且不说这个解决方案严重依赖宿主环境超级无聊
以前试图用这个观察Ucren的函数来的 失败了就没再看过




麻烦你仔细看看上面我给出的链接,然后再自己动手试试看,Dean Edwards大人可不是盖的,这个方法人家用到了Base2库里面……

http://dean.edwards.name/weblog/2006/11/hooray/

// create an <iframe>
var iframe = document.createElement("iframe");
iframe.style.display = "none";
// write a script into the <iframe> and steal its Array object
document.body.appendChild(iframe);
frames[frames.length - 1].document.write("<script>parent.Array2 = Array;<\/script>");


alert(Array2 == Array); // => false
Array2.prototype.each = function(iterator) {  // iterate};
var list1 = new Array(1, 2, 3);
list1.each(print); // => ERROR!
var list2 = new Array2(1, 2, 3);
list2.each(print); // => 1, 2, 3// hooray!


还是那句话,多动手试试……

嗯 不错 果然可以
虽然是小聪明
19 楼 zhxp791008 2008-07-16  
可以使用自定义一个类,对你需要扩展的东东进行包装。
再加入你所需要加入的function或属性.
18 楼 笨笨狗 2008-07-15  
csf178 写道
以前try抛出来个安全异常
现在try了 结果是IE的Array2==Array为true
FF抛异常 麻烦try出来的同学贴个代码看看

且不说这个解决方案严重依赖宿主环境超级无聊
以前试图用这个观察Ucren的函数来的 失败了就没再看过




麻烦你仔细看看上面我给出的链接,然后再自己动手试试看,Dean Edwards大人可不是盖的,这个方法人家用到了Base2库里面……

http://dean.edwards.name/weblog/2006/11/hooray/

// create an <iframe>
var iframe = document.createElement("iframe");
iframe.style.display = "none";
// write a script into the <iframe> and steal its Array object
document.body.appendChild(iframe);
frames[frames.length - 1].document.write("<script>parent.Array2 = Array;<\/script>");


alert(Array2 == Array); // => false
Array2.prototype.each = function(iterator) {  // iterate};
var list1 = new Array(1, 2, 3);
list1.each(print); // => ERROR!
var list2 = new Array2(1, 2, 3);
list2.each(print); // => 1, 2, 3// hooray!


还是那句话,多动手试试……
17 楼 dempire 2008-07-14  
什么都可以污染,就是别污染Object
16 楼 csf178 2008-07-14  
以前try抛出来个安全异常
现在try了 结果是IE的Array2==Array为true
FF抛异常 麻烦try出来的同学贴个代码看看

且不说这个解决方案严重依赖宿主环境超级无聊
以前试图用这个观察Ucren的函数来的 失败了就没再看过
15 楼 achun 2008-07-14  
笨笨狗 写道

这不是我说的,你可以自己去看看Dean Edwards的介绍,或许,你真的没有try就断章取义了?

http://dean.edwards.name/weblog/2006/11/hooray/


在没有自行研究的前提下,不要随便否定别人的观点说法……

嘿嘿,果然早有人用过这种方法,
英文不好,就是不行呀,总要看到中文的解释才会去看,自己搜到了,一大堆英文,自己也很难硬着头皮看.
14 楼 笨笨狗 2008-07-14  
Every JavaScript environment (i.e. a browser window or iframe) has its own copy of the core JavaScript objects and classes. What if we “borrow” one of those objects?
13 楼 笨笨狗 2008-07-14  
csf178 写道
笨笨狗 写道
其实,要解决这个问题,如果你不嫌麻烦,可以在同一个页面上生成一个隐藏的iframe,然后,扩展这个iframe里面的Array对象,并使用它来生产你要的数组实例,这样就能保证你父页面的原型纯净……

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

这个其实是不允许的 你可以try一下


这不是我说的,你可以自己去看看Dean Edwards的介绍,或许,你真的没有try就断章取义了?

http://dean.edwards.name/weblog/2006/11/hooray/


在没有自行研究的前提下,不要随便否定别人的观点说法……
12 楼 achun 2008-07-14  
我打算放弃了,
因为我发现自己犯了一个显著的错误,
就是JavaScript对非值类型总是引用的(当然也有特例,就是固有对象的prototype成员).
因此我还是不要费这个力气了,还是用常规手段吧.
现有的研究得到的技巧,在使用中灵活运用就行了.
11 楼 csf178 2008-07-14  
<div class='quote_title'>achun 写道</div>
<div class='quote_div'>
<p>偶还是不死心,我试试看能不模式化实例继承(扩展).</p>
<p>其实这个帖子是</p>
<p><a href='../../../../../../topic/214285' target='_blank'>http://www.iteye.com/topic/214285</a></p>
<p> </p>
<p>这个帖子的技术基础,我继续试试有没有模式化实例的方法.</p>
</div>
<p><br/>又稍微看了一下 以前我也研究过类似的 你这东西用来搜索不错 相当于以原型方式高速复制对象</p>
<p>可以代替数组的slice提高搜索效率</p>
10 楼 achun 2008-07-14  
<p>偶还是不死心,我试试看能不模式化实例继承(扩展).</p>
<p>其实这个帖子是</p>
<p><a href='../../../../../../topic/214285' target='_blank'>http://www.iteye.com/topic/214285</a></p>
<p> </p>
<p>这个帖子的技术基础,我继续试试有没有模式化实例的方法.</p>
9 楼 achun 2008-07-14  
csf178 写道
achun 写道
csf178 写道
array的length不正确

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

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

Function更是如此

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


呵呵,还是老老实实的 用实例扩展方法吧.
8 楼 csf178 2008-07-14  
for..in其实就是迭代器 可以针对任何集合使用的
JS1.8还可以改变默认行为迭代range呢
7 楼 csf178 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的话就要稍微处理一下了
6 楼 csf178 2008-07-14  
achun 写道
csf178 写道
array的length不正确

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

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

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

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

这个其实是不允许的 你可以try一下
4 楼 achun 2008-07-14  
笨笨狗 写道
其实,要解决这个问题,如果你不嫌麻烦,可以在同一个页面上生成一个隐藏的iframe,然后,扩展这个iframe里面的Array对象,并使用它来生产你要的数组实例,这样就能保证你父页面的原型纯净……

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

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

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

相关推荐

    MongoDB分片集群搭建教程:副本集创建与数据分片

    内容概要:本文提供了详细的MongoDB分片集群的搭建指导,涵盖了从环境准备、配置文件编写、副本集的建立、主节点的选择、配置服务器和数据分片服务器的配置到最后的路由节点的搭建与操作整个流程,以及对数据库的哈希与范围两种分片策略的应用介绍和具体命令执行。 适合人群:熟悉NoSQL数据库概念并对MongoDB有一定了解的技术人员,尤其是在大型数据管理和分布式数据库架构设计中有需求的开发者。 使用场景及目标:帮助技术人员掌握构建高效能、高可用性的MongoDB分片集群的方法,适用于处理大规模、实时性强的数据存储与读取场景。 其他说明:文中通过实例演示了每个步骤的具体操作方法,便于跟随文档实操,同时也介绍了可能遇到的问题及其解决方案,如在没有正确配置的情况下试图写入数据时出现错误等情况的处理。

    CPPC++_嵌入式硬件的物联网解决方案blinker库与Arduino ESP8266 ESP32一起工作.zip

    CPPC++_嵌入式硬件的物联网解决方案blinker库与Arduino ESP8266 ESP32一起工作

    CPPC++_逆向调用QQ Mojo IPC与WeChat XPlugin.zip

    CPPC++_逆向调用QQ Mojo IPC与WeChat XPlugin

    CPPC++_现代活动指标.zip

    CPPC++_现代活动指标

    CPPC++_Xournal是一款手写笔记软件,支持PDF注释,使用C语言编写,支持GTK3,支持Linux,如Ubu.zip

    CPPC++_Xournal是一款手写笔记软件,支持PDF注释,使用C语言编写,支持GTK3,支持Linux,如Ubu

    基于SSM学生实习管理系统前台小程序与后台管理系统开发实践

    资源概述: 本资源提供了一套完整的学生实习管理系统解决方案,涵盖了前台小程序页面与后台管理系统两大模块。前台小程序页面设计简洁直观,用户可根据不同身份(学生或企业)进行登录。学生用户能够方便地浏览并投递感兴趣的实习岗位,而企业用户则能轻松发布实习信息,吸引优秀人才。后台管理系统功能全面,包括个人中心、首页、学生管理、教师管理、企业管理、招聘管理、评分管理以及实习管理等多个方面,为管理员提供了强大的数据管理和操作工具。 技术栈亮点: SSM框架:系统后台采用Spring、Spring MVC和MyBatis Plus(简称SSM)作为核心开发框架,确保了系统的稳定性、可扩展性和可维护性。Spring作为控制反转(IoC)和面向切面编程(AOP)的容器,为系统提供了强大的业务逻辑处理能力;Spring MVC则负责处理Web请求和响应,实现了前后端的分离;MyBatis Plus作为持久层框架,简化了数据库操作,提高了开发效率。 MySQL数据库:系统采用MySQL作为数据库存储解决方案,支持大数据量的存储和高效查询。 如有侵权请联系我删除,谢谢

    微服务闪聚支付项目.zip

    微服务闪聚支付项目

    Rust 与 Java 互调实战示例

    博客链接 https://blog.csdn.net/weixin_47560078/article/details/143714557 文章从原理介绍出发,实现了 Rust 与 Java 的互调。利用 JNI 技术,可以充分发挥 Rust 的性能优势,同时保持 Java 的跨平台特性。这种技术组合适用于对性能要求较高的应用场景,如图像处理、数据分析和系统级编程等。

    CPPC++_这是我翻译的艾根中文文档.zip

    cppc++

    Matlab实现斑马优化算法ZOA-TCN-Multihead-Attention多输入单输出回归预测算法研究.rar

    1.版本:matlab2014/2019a/2024a 2.附赠案例数据可直接运行matlab程序。 3.代码特点:参数化编程、参数可方便更改、代码编程思路清晰、注释明细。 4.适用对象:计算机,电子信息工程、数学等专业的大学生课程设计、期末大作业和毕业设计。 替换数据可以直接使用,注释清楚,适合新手

    Matlab实现雪融优化算法SAO-TCN-Multihead-Attention多输入单输出回归预测算法研究.rar

    1.版本:matlab2014/2019a/2024a 2.附赠案例数据可直接运行matlab程序。 3.代码特点:参数化编程、参数可方便更改、代码编程思路清晰、注释明细。 4.适用对象:计算机,电子信息工程、数学等专业的大学生课程设计、期末大作业和毕业设计。 替换数据可以直接使用,注释清楚,适合新手

    分布式事务lcn.zip

    分布式事务lcn

    基于Simulink的正弦波PWM技术和三次谐波注入PWM技术研究.rar

    1.版本:matlab2014/2019a/2024a 2.附赠案例数据可直接运行matlab程序。 3.代码特点:参数化编程、参数可方便更改、代码编程思路清晰、注释明细。 4.适用对象:计算机,电子信息工程、数学等专业的大学生课程设计、期末大作业和毕业设计。

    【风电功率预测】基于BiTCN的风电功率多变量输入预测研究附Matlab代码.rar

    1.版本:matlab2014/2019a/2024a 2.附赠案例数据可直接运行matlab程序。 3.代码特点:参数化编程、参数可方便更改、代码编程思路清晰、注释明细。 4.适用对象:计算机,电子信息工程、数学等专业的大学生课程设计、期末大作业和毕业设计。

    CPPC++_这是由一块迷你带OV2640双DRV8833驱动TypeC接口PSRAM的ESP32PicoD4开发板驱.zip

    cppc++

    JAVA安卓手机与电脑的socket通信源码数据库 其他源码类型 WinForm

    安卓手机与电脑的socket通信源码

    Anaconda:JupyterNotebook使用教程.docx

    Anaconda:JupyterNotebook使用教程.docx

    Amazon S3:S3静态网站托管教程.docx

    Amazon S3:S3静态网站托管教程.docx

    Python商品销售数据分析可视化项目源码(期末大作业).zip

    Python商品销售数据分析可视化项目源码(期末大作业).zip,个人经导师指导并认可通过的98分大作业设计项目。主要针对计算机相关专业的正在做期末大作业设计的学生和需要项目实战练习的学习者,可作为课程设计、期末大作业,代码资料完整下载可用。 Python商品销售数据分析可视化项目源码(期末大作业).zip,个人经导师指导并认可通过的98分大作业设计项目。主要针对计算机相关专业的正在做期末大作业设计的学生和需要项目实战练习的学习者,可作为课程设计、期末大作业,代码资料完整下载可用。Python商品销售数据分析可视化项目源码(期末大作业).zip,个人经导师指导并认可通过的98分大作业设计项目。主要针对计算机相关专业的正在做期末大作业设计的学生和需要项目实战练习的学习者,可作为课程设计、期末大作业,代码资料完整下载可用。Python商品销售数据分析可视化项目源码(期末大作业).zip,个人经导师指导并认可通过的98分大作业设计项目。主要针对计算机相关专业的正在做期末大作业设计的学生和需要项目实战练习的学习者,可作为课程设计、期末大作业,代码资料完整下载可用。Python商品销售数据分析

    CPPC++_wechathookWeChatApi微信Api微信hook微信接口python微信接口java微信Ap.zip

    CPPC++_wechathookWeChatApi微信Api微信hook微信接口python微信接口java微信Ap

Global site tag (gtag.js) - Google Analytics