<html> <head><meta http-equiv=content-type content="text/html; charset=utf-8"> <title>测试”给所有JavaScript对象扩展属性、方法”</title> </head> <body> <script type="text/javascript" language="JavaScript" src="/jcore/resource /javascript/Jcore.js"></script> <script type="text/javascript" language="JavaScript">
// 功能描述:将Array的一些函数扩展到通用对象里 // 由于Object是所有对象的祖先对象,因此我们不能用同样的名字写到 // Object里,除非里面的算法我们自己写,否则会导致Object里的方法调用Array里的方法 // Array又从Object里继承,导致循环调用,堆栈溢出 // 另外,笔者这里不打算重新写这些算法,因为Array的这些算法已经由二进制代码完成, // 它的性能肯定比我们的实现快。不过,笔者这里使用了一点手段,避免这个问题.... // 这里出现后就提到"Jcore.js"里,以后章节将不再出现 // 返回信息:function对象的时候返回绑定后的function对象,否则返回绑定后的对象 // 使用指南:例子代码比较多,这里就不给出使用举例了,参见下面的例子 // 应用范围:各种Web客户端和服务端开发 Object.exo({ // 匿名函数在exo执行前已经先执行,因此Array.prototype里的东西我们已经保存了一份, // 这样就不怕下面重写带来的灾难了。另外,你也不用担心,这里的_start只保留了一个true // 读者应该学会这种方式,在一个常规变量的初始化时做一定的工作。不过要注意的是 // 这里的匿名函数里不能使用当前对象this里的东西,也不能访问this,因为这时候this // 还没有创建呢,它不同于function,function在定义的过程中就已经可以使用this了。 // Object对象的this只能在它的函数类型里在调用的时候才可以使用 _start:(function() { // 这里我们将一个串使用方法split转换为Array后立刻进入迭代状态 ['concat','join','pop','push','reverse','shift', 'slice','sort','splice','unshift'].each(function() { // 这里先保留下来,下面好用 Object.prototype["_" + this] = Array.prototype[this]; }); return true; })(), concat:function() { try { Object.prototype["concat"].name = "concat"; // 这里最关键的是必须先把this通过_A()转换为有效的数组, // 否则会无法将内部的元素正确加进去 // 同时我们防止上面描述中的循环调用,直接调用上面保留的下画线方法。 return []._concat.apply(_A(this), _A(arguments)); }catch(e){fnCatch(e)} }, push:function() { try { Object.prototype["push"].name = "push"; return []._push.apply(this, _A(arguments)); }catch(e){alert(e.message);fnCatch(e)} }, join:function() { try { Object.prototype["join"].name = "join"; // 下面两种写法都正确 // return _A(this)._join(_A(arguments)[0]); return []._join.apply(this, _A(arguments)); }catch(e){fnCatch(e)} }, pop:function() { try { Object.prototype["pop"].name = "pop"; return []._pop.apply(this); }catch(e){fnCatch(e)} }, reverse:function() { try { Object.prototype["reverse"].name = "reverse"; return []._reverse.apply(this, _A(arguments)); }catch(e){fnCatch(e)} }, shift:function() { try { Object.prototype["shift"].name = "shift"; return []._shift.apply(this, _A(arguments)); }catch(e){fnCatch(e)} }, slice:function() { try { Object.prototype["slice"].name = "slice"; return []._slice.apply(this, _A(arguments)); }catch(e){fnCatch(e)} }, sort:function() { try { Object.prototype["sort"].name = "sort"; return []._sort.apply(this, _A(arguments)); }catch(e){fnCatch(e)} }, splice:function() { try { Object.prototype["splice"].name = "splice"; return []._splice.apply(this, _A(arguments)); }catch(e){fnCatch(e)} }, unshift:function() { try { Object.prototype["unshift"].name = "unshift"; return []._unshift.apply(this, _A(arguments)); }catch(e){fnCatch(e)} } });
try { var oTestObj = {}; oTestObj.push("谦虚是迈向进步的助燃剂![2007-8-11 22:15]",444,232); var arrTmp = oTestObj.concat(["人生不过百年之身,行人方便即是行己方便,善于它人就是善于自己", "天地虽大,社会却小啊!"]); // 得到: 232 alert(oTestObj.pop()); // 效果参见图3-27 alert(oTestObj[0]); // 通用对象的join功能,参见图3-28 alert(arrTmp.join("\n")); // 默认排序是升序,将最大的排在后面,这里我们随便测试一下 // 自己写排序函数,将大的排在前面 // 排序功能测试,参见图3-29 alert(oTestObj.sort(function(a,b) { return a > b ? -1 : 1; return 0; }).join("\n")); // 可以看出,原有对象的相关功能是保留了的,效果参见图3-30 alert([234,33].concat([11,33]).join("\n"));
}catch(e){alert("Err" + e.message)}
--> </script> </body> </html> |