手机版

JavaScript从数组的索引()中渗透对象的属性机制

时间:2021-10-31 来源:互联网 编辑:宝哥软件园 浏览:

在JavaScript中,可以使用Array构造函数创建数组,也可以使用[]快速创建数组,这也是首选方法。数组是从对象继承的原型,它没有类型的特殊返回值,只有“对象”。

在js中,可以说一切都是对象,数组也是数组。

很多对象都有很多方便的方法,比如push、concat、slice等等,但是如果有些对象没有实现这些方法,我们还是要用这些函数。那我们该怎么办?

1.许多方法提供了非常高效的实现,我们可以模仿它们的实现。

例如,IE8以下的浏览器不支持数组的indexOf方法。为了使数组支持indexOf,我们可以自己编写一个方法来实现indexOf方法:

(用IE浏览器调试,按F12选择浏览器版本到IE5。)

var arr=[,];if(array . prototype . indexOf){ alert('您的浏览器支持index of方法,');} else {alert('您的浏览器不支持indexOf方法。);}if(!array . prototype . indexof){ array . prototype . indexof=function(item){ for(var I=;我这个长度;i ) {if(这个[I]==项){ return I;} }返回-;} } alert(arr . indexof());alert(arr . indexof());当然,这个方法很垃圾。在这里,具体实现我就不出丑了,在百度上提供一个版本的副本:

如果你感兴趣,你可以看看v8发动机是如何实现的:https://github.com/v8/v8/blob/master/src/js/array.js.

if(!array . prototype . indexof){ array . prototype . indexof=function(ELT/*,from */){ var len=this . length;var from=Number(参数[])| |;从=(从)?数学。天花板(来自):数学。地板(来自);if(from)from=len;for(;来自lenfrom ){if (from在本例中[from]===elt)返回from;}返回-;};} 2.继承——call并应用方法。

如果我们有每个对象,那么每个对象编写自己的实现是不是很麻烦?

在高级语言中,我们可以使用继承来解决问题,比如下面的java代码:

public class MyListE扩展了ArrayList { public void my add(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);//输出参数for(var I=;长度;i ){console.log('Add: '参数[I]);} } var obj=new myObject();obj.add(,);这里可以看到,虽然myAdd方法是以高级语言的继承方式实现的,但是myAdd方法现在只能传递一个参数。如果要传递多个参数,需要编写一个public void myAdd(E[] e)方法甚至是一个public void myadd (liste)方法。但是JS可以用一种方式来完成,所有的输入参数都用参数对象来表示,这是高级语言很难做到的。

(ps,其实可以写公共void myAdd(E.E)在java中,这是一个不定参数,它的用法与public void myAdd(E[] e)相同。

和callapply方法用于更改函数中该指针的指向。call只有两个参数,而apply通常在知道参数数量后使用。下面是一个例子:

var Obj=函数(名称){ this.name=name} Obj . prototype . GetName=function(){ return this . name;} var Obj 1=new Obj(' Zou ');var obj 2={ name : ' Andy ' };var name=obj 1 . GetName . call(obj 2);警报(名称);参考是:

apply(object,arg1,arg2,)调用(对象,[arg1,arg2,])

Call后面只能跟一个“数组”,包括所有参数。Apply是一种语法糖。如果知道参数个数,使用apply会非常方便。

上述对象也可以为空或未定义,因此该对象是一个全局对象(窗口),例如,继续上述示例:

var name=' gooalert(obj 1 . GetName . call(null));(在严格模式下,由于全局对象为null,将引发异常:unsughttypeerror :无法读取null的属性“name ”) 3。object . definepreproperty。

(注意:不要在IE8以下使用这类功能。)

微软:将属性添加到对象,或修改现有属性的特性。

吸气剂、设置剂、

其实射流研究…中对于对象的属性也有吸气剂和作曲者函数,不过个人觉得射流研究…中的吸气剂和作曲者更像C#一些。

例如下面的代码就定义了一个获取器/设置器:

function myobj(){ }对象。define property(myobj。prototype,' length ',{ get : function(){ return this。长度_;//这里不能是长度。},设置:函数(值){返回这个。length _=值;}});注释的地方不能是长度,否则会无限递归。

也可以去掉设置,让长度变量只读。

对象。define property(myobj。prototype、' length '、{ get: function(){ return this。长度_;//这里不能是长度。},/*设置:函数(值){返回这个。length _=值;}*/});myobj。长度=3;这个代码会抛出异常:未捕获类型错误:无法设置只有一个吸气剂的#myobj的属性长度。

要让对象的属性只读,还可以用可写:false,

对象。define property(myobj。prototype,“length”,{可写: false });可写:false不能与预备开始共存,否则会抛出类型错误。

可配置:是否能用删除语句删除,但是可配置的属性好像在严格模式下才有效,这样的代码在非严格模式下仍然能执行:(严格模式报错)

对象。定义属性(myobj。原型,‘length’,{ configuration ble : false });var obj=new myobj();删除长度值:指定该对象的固定值价值:10,表示这个对象初始值为10.

在非严格模式下,这样的代码不会报错,严格模式下会报错:

对象。define property(myobj。prototype,“length”,{writable:false,value : ' 10 ' });var obj=new myobj();obj.length=100可以用getowntpropertysdescriptor来获取并修改这些值,比如说,现在我的长度属性是只读的。

运行这样的代码,结果却报错了:

对象。define property(myobj。prototype,' length ',{value:writable:false,});var描述符=对象。getowntpropertysdescriptor(myobj。原型,‘长度’);descriptor.writable=trueobject。define property(myobj。原型,‘长度’,描述符);未捕获类型错误:无法重新定义属性:长度这是因为可配置的的默认值是假的,在调用了定义属性之后,可配置就具有错误的属性,这样就不能逆转了。以后就不能改了。

所以必须使用可配置:路径,这个对象属性才是可以修改的,完整的代码如下:

对象。定义属性(myobj。prototype,' length ',{value:writable:false,可配置: true });var描述符=对象。getowntpropertysdescriptor(myobj。原型,‘长度’);descriptor.writable=trueobject。define property(myobj。原型,‘长度’,描述符);myobj。原型。长度=;var obj=new myobj();警惕长度);可以加上一句descriptor.configurable=false

表示这个属性我修改了,以后你们都不能再修改了

这个特性在很多时候也有用,数组排列的按压弹出等方法,如果使用打电话、申请,要求对象的长度可变。如果对象的长度属性只读,那么调用呼叫、申请时,会抛出异常。

就比如domtokinglist对象,它的长度就是不可以变的。我拿到了一个数字正射影像图对象DOMTokenList,

但是它的可配置的是没错,我们可以修改让它的长度属性可以变啊:

看见没,这个可配置的是没错,而作曲者是未定义,我们给它写一个设置方法,不就可以了吗?

var描述符=对象。getowntpropertysdescriptor(DOM tk quire。原型,‘长度’);descriptor.set=函数(值){this.length=值;}对象。define property(DOM tk quire。原型,‘长度’,描述符);然后运行,

又抛出了一个异常,未捕获范围错误:超过了最大调用堆栈大小(…)

这是因为,我们在设定这个长度时,它会在我们写的那个设置方法中无限递归。

因此,我们需要使用删除消除长度属性的影响,也就是:

var描述符=对象。getowntpropertysdescriptor(DOM tk quire。原型,‘长度’);描述符。set=function(value){ delete DOM tk quire。原型。长度;this.length=值;}对象。define property(DOM tk quire。原型,‘长度’,描述符);这样,DOMTokenList也就支持了用力,爸爸等等操作了。

数组。原型。用力。调用(文档。尸体。类别列表,‘ABC’)然后再行封装

domtokinlist。原型。push=function(){ array。原型。用力。调用(文档。尸体。类列表,数组。原型。切片。调用(参数));}Array.prototype.slice.call(参数)方法用于把争论对象转换为数组。

版权声明:JavaScript从数组的索引()中渗透对象的属性机制是由宝哥软件园云端程序自动收集整理而来。如果本文侵犯了你的权益,请联系本站底部QQ或者邮箱删除。