JavaScript从数组的indexOf()深化之Object的Property机制__第1页
JavaScript从数组的indexOf()深化之Object的Property机制__第2页
JavaScript从数组的indexOf()深化之Object的Property机制__第3页
JavaScript从数组的indexOf()深化之Object的Property机制__第4页
JavaScript从数组的indexOf()深化之Object的Property机制__第5页
已阅读5页,还剩8页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

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 (Atotype.indexOf) alert("你的扫瞄器支持indexOf方法。"); else alert("你的扫瞄器不支持indexOf方法。");

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

4、 = function(elt /*, from*/) 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方法 假如我们每有一个对象,那每个对象就要自己写一遍实现是不是很麻烦? 在高级语言中

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

6、 /输出arguments for(var i=;iarguments.length;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对象表示输入的全部参数,这是高级语言难以做到的。 (p

7、s,其实在java中可以写public void myAdd(E. e),这个是不定参数,用法上public void myAdd(E e)是一样的) call和apply方法用于转变函数内this指针的指向,call只有两个参数,而apply通常是知道参数个数之后才用法的,下面以例子说明: var Obj = function(name) = name; Ototype.getName = function() return ; var obj1 =new Obj("zou"); var obj2 = name:'

8、andy' var name = obj1.getName.call(obj2); alert(name); 参考是: apply(object,arg1,arg2,.) call(object,arg1,arg2,.) call后面只能跟一个“数组”,包括了全部的参数。而apply则是一颗语法糖,假如知道参数的个数,用apply将很便利。 上面的object也可以是null或者undefined,这样,这个object就是global object(window),例如,还是接着上例: var name = 'goo' alert(obj1.getName.call(

9、null); (在严格模式下,由于全局对象是null,故会抛出特别:Uncaught TypeError: Cannot read property 'name' of null) 3、Object.defineProperty (留意:不要在IE8以下用法该类特性) 微软:将属性添加到对象,或修改现有属性的特性。 getter、setter, 其实js中对于对象的属性也有getter和setter函数,不过个人觉得js中的getter和setter更像C#一些。 例如下面的代码就定义了一个getter/setter: function myobj() Object.defin

10、eProperty(totype,'length', get:function() return this.length_; /这里不能是length。 , set:function(value) return this.length_=value; ); 说明的地方不能是length,否则会无限递归。 也可以去掉set,让length变量只读。 Object.defineProperty(totype,'length', get:function() return this.length_; /这里不能是length。 ,

11、/*set:function(value) return this.length_=value; */ ); myobj.length = 3; 这个代码会抛出特别:Uncaught TypeError: Cannot set property length of #myobj which has only a getter。 要让对象的属性只读,还可以用writable:false, Object.defineProperty(totype,'length', writable:false ); writable:false不能与get set共存,否则会抛

12、出Type Error。 configurable:是否能用delete语句删除,但是configurable属性似乎在严格模式下才有效,这样的代码在非严格模式下仍旧能执行:(严格模式报错) Object.defineProperty(totype,'length', configurable:false ); var obj = new myobj(); delete obj.length; value:指定该对象的固定值。value:10,表示这个对象初始值为10. 在非严格模式下,这样的代码不会报错,严格模式下会报错: Object.defineProp

13、erty(totype,'length', writable:false, value:'10' ); var obj = new myobj(); obj.length = 100; 可以用getOwnPropertyDescriptor来猎取并修改这些值,比如说,现在我的length属性是只读的。 运行这样的代码,结果却报错了: Object.defineProperty(totype,'length', value:, writable:false, ); var descriptor = Object.

14、getOwnPropertyDescriptor(totype, "length"); descriptor.writable = true; Object.defineProperty(totype,'length',descriptor); Uncaught TypeError: Cannot redefine property: length 这是由于configurable的默认值是false,在调用了defineProperty之后,configurable就具有false属性,这样就不能逆转了。以后就不能改了。

15、 所以必需用法 configurable:true,这个对象属性才是可以修改的,完整的代码如下: Object.defineProperty(totype,'length', value:, writable:false, configurable:true ); var descriptor = Object.getOwnPropertyDescriptor(totype, "length"); descriptor.writable = true; Object.defineProperty(toty

16、pe,'length',descriptor); totype.length = ; var obj = new myobj(); alert(obj.length); 可以加上一句descriptor.configurable = false; 表示这个属性我修改了,以后你们都不能再修改了 这个特性在许多时候也有用,数组Array的push pop等方法,假如用法call、apply,要求对象的length可变。假如对象的length属性只读,那么调用call、apply时,会抛出特别。 就比如DOMTokenList对象,它的length就是不行以变的。我

17、拿到了一个DOM对象DOMTokenList, 但是它的configurable是true,我们可以修改让它的length属性可以变啊: 观察没,这个configurable是true,而setter是undefined,我们给它写一个set方法,不就可以了吗? var descriptor = Object.getOwnPropertyDescriptor(DOMTokenLtotype,'length'); descriptor.set = function(value) this.length = value; Object.defineProperty(D

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

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论