JavaScript从数组的indexOf()深化之Object的Property机制_.docx

上传人:PIYPING 文档编号:11644400 上传时间:2021-08-27 格式:DOCX 页数:13 大小:15.67KB
返回 下载 相关 举报
JavaScript从数组的indexOf()深化之Object的Property机制_.docx_第1页
第1页 / 共13页
JavaScript从数组的indexOf()深化之Object的Property机制_.docx_第2页
第2页 / 共13页
JavaScript从数组的indexOf()深化之Object的Property机制_.docx_第3页
第3页 / 共13页
JavaScript从数组的indexOf()深化之Object的Property机制_.docx_第4页
第4页 / 共13页
JavaScript从数组的indexOf()深化之Object的Property机制_.docx_第5页
第5页 / 共13页
亲,该文档总共13页,到这儿已超出免费预览范围,如果喜欢就下载吧!
资源描述

《JavaScript从数组的indexOf()深化之Object的Property机制_.docx》由会员分享,可在线阅读,更多相关《JavaScript从数组的indexOf()深化之Object的Property机制_.docx(13页珍藏版)》请在三一文库上搜索。

1、JavaScript从数组的indexOf()深化之Object的Property机制_ 这篇文章主要介绍了JavaScript从数组的indexOf()深化Object的Property机制的相关资料,需要的伴侣可以参考下 在JavaScript中,数组可以用法Array构造函数来创建,或用法快速创建,这也是首选的方法。数组是继承自Object的原型,并且他对typeof没有特别的返回值,他只返回object。 js中,可以说万物皆对象(object),一个数组也是一个对象(array)。 许多对象都有许多很便利的方法 比如数组的push,concat,slice等等,但是假如一些对象,它没

2、有实现这些方法,我们还是想用法这些功能。那该怎么办呢? 1、许多方法都供应了特别高效的实现, 我们可以仿照它们的实现。 比如IE8以下的扫瞄器不支持Array的indexOf方法,为了让数组支持indexOf,我们可以自己写一个方法,实现indexOf方法: (用IE扫瞄器调试 按F12,可以选择扫瞄器版本到IE5。) var arr = , , , ; if (Array.prototype.indexOf) alert(你的扫瞄器支持indexOf方法。); else alert(你的扫瞄器不支持indexOf方法。); if (!Array.prototype.indexOf) Arra

3、y.prototype.indexOf = function(item) for (var i = ; i this.length; i+) if(thisi=item) return i; return -; alert(arr.indexOf(); alert(arr.indexOf(); 当然这个方法是很垃圾的。在这里具体的实现 我就不献丑了,供应一个百度上copy的版本: 有爱好的话可以看看v8引擎是怎么实现的:https:/ if (!Array.prototype.indexOf) Array.prototype.indexOf = function(elt /*, from*/)

4、 var len = this.length ; var from = Number(arguments) | ; from = (from ) ? Math.ceil(from) : Math.floor(from); if (from ) from += len; for (; from len; from+) if (from in this thisfrom = elt) return from; return -; ; 2、继承call和apply方法 假如我们每有一个对象,那每个对象就要自己写一遍实现是不是很麻烦? 在高级语言中,我们可以用继承来解决问题,比如下面的java代码:

5、public class MyListE extends ArrayListE public void myAdd(E e) super.add(e); System.out.println(Add:+e); 但是js中没有继承的概念啊,我们可以用call和apply来解决这样的问题。 上面的代码就可以改写为: var myObject = function() myObject.prototype.add = function() Array.prototype.push.call(this,arguments); /输出arguments for(var i=;iarguments.len

6、gth;i+) console.log(Add:+argumentsi); var obj = new myObject(); obj.add(,); 这里可以看到:虽然用高级语言的继承方式实现了myAdd方法,但是现在myAdd方法只能传一个参数,假如要传多个参数,则需要再写一个public void myAdd(E e)方法,甚至是public void myAdd(ListE e)方法。而JS用一个方法就可以搞定,用arguments对象表示输入的全部参数,这是高级语言难以做到的。 (ps,其实在java中可以写public void myAdd(E. e),这个是不定参数,用法上pub

7、lic void myAdd(E e)是一样的) call和apply方法用于转变函数内this指针的指向,call只有两个参数,而apply通常是知道参数个数之后才用法的,下面以例子说明: var Obj = function(name) this.name = name; Obj.prototype.getName = function() return this.name; var obj1 =new Obj(zou); var obj2 = name:andy; var name = obj1.getName.call(obj2); alert(name); 参考是: apply(ob

8、ject,arg1,arg2,.) call(object,arg1,arg2,.) call后面只能跟一个“数组”,包括了全部的参数。而apply则是一颗语法糖,假如知道参数的个数,用apply将很便利。 上面的object也可以是null或者undefined,这样,这个object就是global object(window),例如,还是接着上例: var name = goo; alert(obj1.getName.call(null); (在严格模式下,由于全局对象是null,故会抛出特别:Uncaught TypeError: Cannot read property name o

9、f null) 3、Object.defineProperty (留意:不要在IE8以下用法该类特性) 微软:将属性添加到对象,或修改现有属性的特性。 getter、setter, 其实js中对于对象的属性也有getter和setter函数,不过个人觉得js中的getter和setter更像C#一些。 例如下面的代码就定义了一个getter/setter: function myobj() Object.defineProperty(myobj.prototype,length, get:function() return this.length_; /这里不能是length。 , set:f

10、unction(value) return this.length_=value; ); 说明的地方不能是length,否则会无限递归。 也可以去掉set,让length变量只读。 Object.defineProperty(myobj.prototype,length, get:function() return this.length_; /这里不能是length。 , /*set:function(value) return this.length_=value; */ ); myobj.length = 3; 这个代码会抛出特别:Uncaught TypeError: Cannot s

11、et property length of #myobj which has only a getter。 要让对象的属性只读,还可以用writable:false, Object.defineProperty(myobj.prototype,length, writable:false ); writable:false不能与get set共存,否则会抛出Type Error。 configurable:是否能用delete语句删除,但是configurable属性似乎在严格模式下才有效,这样的代码在非严格模式下仍旧能执行:(严格模式报错) Object.defineProperty(myo

12、bj.prototype,length, configurable:false ); var obj = new myobj(); delete obj.length; value:指定该对象的固定值。value:10,表示这个对象初始值为10. 在非严格模式下,这样的代码不会报错,严格模式下会报错: Object.defineProperty(myobj.prototype,length, writable:false, value:10 ); var obj = new myobj(); obj.length = 100; 可以用getOwnPropertyDescriptor来猎取并修改

13、这些值,比如说,现在我的length属性是只读的。 运行这样的代码,结果却报错了: Object.defineProperty(myobj.prototype,length, value:, writable:false, ); var descriptor = Object.getOwnPropertyDescriptor(myobj.prototype, length); descriptor.writable = true; Object.defineProperty(myobj.prototype,length,descriptor); Uncaught TypeError: Cann

14、ot redefine property: length 这是由于configurable的默认值是false,在调用了defineProperty之后,configurable就具有false属性,这样就不能逆转了。以后就不能改了。 所以必需用法 configurable:true,这个对象属性才是可以修改的,完整的代码如下: Object.defineProperty(myobj.prototype,length, value:, writable:false, configurable:true ); var descriptor = Object.getOwnPropertyDescr

15、iptor(myobj.prototype, length); descriptor.writable = true; Object.defineProperty(myobj.prototype,length,descriptor); myobj.prototype.length = ; var obj = new myobj(); alert(obj.length); 可以加上一句descriptor.configurable = false; 表示这个属性我修改了,以后你们都不能再修改了 这个特性在许多时候也有用,数组Array的push pop等方法,假如用法call、apply,要求对

16、象的length可变。假如对象的length属性只读,那么调用call、apply时,会抛出特别。 就比如DOMTokenList对象,它的length就是不行以变的。我拿到了一个DOM对象DOMTokenList, 但是它的configurable是true,我们可以修改让它的length属性可以变啊: 观察没,这个configurable是true,而setter是undefined,我们给它写一个set方法,不就可以了吗? var descriptor = Object.getOwnPropertyDescriptor(DOMTokenList.prototype,length); de

17、scriptor.set = function(value) this.length = value; Object.defineProperty(DOMTokenList.prototype,length,descriptor); 然后运行, 又抛出了一个特别,Uncaught RangeError: Maximum call stack size exceeded() 这是由于,我们在set this.length时,它会在我们写的那个set方法中无限递归。 因此,我们需要用法delete消退length属性的影响,也就是: var descriptor = Object.getOwnPr

18、opertyDescriptor(DOMTokenList.prototype,length); descriptor.set = function(value) delete DOMTokenList.prototype.length; this.length = value; Object.defineProperty(DOMTokenList.prototype,length,descriptor); 这样,DOMTokenList也就支持了push,pop等等操作了。 Array.prototype.push.call(document.body.classList,abc) 然后再行封装 DOMTokenList.prototype.push = function() Array.prototype.push.call(document.body.classList,Array.prototype.slice.call(arguments); Array.prototype.slice.call(arguments)方法用于把arguments对象转换为数组。 .

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 科普知识


经营许可证编号:宁ICP备18001539号-1