ECMAScriptjs object(对象)

http://www.cnblogs.com/pingchuanxin/p/5773326.html

Object(对象)是在富有的编制程序语言中都相当关键的三个定义,对于事物大家得以把她们作为是多个对象,而每一个东西都有谈得来的表示的属性和对于某1音信作出的应和的操作。而这一个东西就改成了事物的天性和方法。

  在JS中大家得以观察的对象常量有如下的形式:

ECMAScript 1

 1 var obj= {
 2 
 3   name:"Arvin",
 4 
 5   lastName:"Huang" ,
 6 
 7   whatsName:function(){
 8 
 9      alert(this.name+" "+this.lastName);   
10 
11   },
12   
13 }

ECMAScript 2

由地点的代码大家能够看看实际上在JS中的对象正是1个以键值对形式储存属性的贰个见面,每一日性质有3个一定的称谓,并与名称相对应的值。其实那种关联是有2个专盛名称的,大家得以叫做映射,当然对于目的的话,除了能够由此那种方式来保证自有总体性,还能通过继承的办法来赢得继承属性。那种艺术我们誉为“原型式继承”。

 

接下去大家将从js对象的本性,属性性情,方法和指标特性等四个方面来学习指标的定义。

1.js对象创设与指标属性。

贰.js对象属性操作。

叁.js对象属性性格。

4.js对象方法。

伍.js对象脾性。

 

1:js对象成立与对目的属性。

  我们先看如下的代码。

ECMAScript 3

 1 var built = function(){
 2     
 3     var me = this;
 4     me.name = "Arvin";
 5 
 6 }
 7 
 8 built.prototype = {
 9     toStr:function(value){
10         alert("there have a " + value);
11     }
12 
13 };
14 
15 var obj = new built();

ECMAScript 4

地点的代码就讲述了壹种大家日常使用到的一种创造对象的主意,使用new关键字来成立2个怀有独立内部存款和储蓄器区域和指向原型的指针的对象。当大家采取的new的时候,js解析器会分配一块内部存款和储蓄器空间,用以存放当前的靶子的自有总体性。之后解析器会给那壹对象七个_proto_品质指向的原型对象内容。

 

再有1种情势大家誉为对象直接量表明的主意,代码如下:

ECMAScript 5

1 var obj = {
2     
3     name:"Arvin",
4 
5     toStr:function(value){
6         alert("there has a "+value);
7     }
8 };

ECMAScript 6

指标直接量便是一直通过花括号包裹的键值对的款型来定义当前指标的。每七个值期间的经过逗号来实行剪切。键和值时期通过冒号来划分。放解析器读取到最近的内容的时候会自动的生成三个对象的剧情并把当前的靶子存款和储蓄在现阶段上下文中。

 

再有1种对象创立的不二诀窍是利用Object.create()方法,这一艺术是ECMAScript5中定义的2个剧情,它是二个静态方法,其使用方法如下。

1 var obj = Object.create({x:1,y:2});//obj继承了属性x和y

那①措施传入的参数是几个对象,并且那1成效的靶子将会作为新的靶子的原型存在。

 

接下去我们来看1看属性。

当大家在chrome的命令杜阿拉运作第二段示例代码的时候大家能够看出如下的内容。

ECMAScript 7可知,当我们在构造函数中央直属机关接动用this指针(指代当前的靶子)添加属性,那时,其实我们的安装的质量是日前的目的特有的性质,独属于当下的目的的,那样的习性称之为自有品质。而在大家定义构造函数的时候,大家为构造函数的prototype属性(指向原型对象),那时大家定义了prototype的情节和艺术。当使用new关键字来举行对象的布局的时候,大家所社团的对象实际是继续了那1原型对象的剧情的,所以大家可以再对象的_proto_品质中能够看见继承与原型对象的内容,但那也是属于当前的目的的,(原型链内容请阅读原型链学习汇总。)那样的性质大家誉为后续属性。

小编们对象属性的档次能够是字符串,数字,true,false,null和undefined,可能是指标的剧情。当然即使字符串,数字,和布尔值固然不是目的,不过性质和不可变对象类似的。

 

我们在此之前说过属性的值是名字和值,在那之中名字是能够是总结空字符串在内的任意字符串,但是属性的值是除这么些之外的,仍是可以够是概念好的存取器方法。如下代码:

 

1 var o = {
2     x:1,3     y:1,4     
5     get r(){return x+y;},
6     set r(value){this.x = value;}
7 }

 

如上代码可知,在目的O中r便是叁个存取器属性内容,存取器属性其实是不足设置的质量的一种,唯有当他具备了getter方法的时候才足以取值的,而又setter方法的时候表示那一品质是可写的,存取其质量实在ECMAScript第55中学才有定义的,实际上是把质量通过函数的法子开始展览与外边的数目交互的。从而使得属性值本人无法直接开始展览配置只怕获取。

存取器属性的写法就像上边代码书写的如出1辙,get关键字空格之后跟属性名称作为函数的称谓,set方法和get方法是均等编写的,只是会传播参数,并且参数的个数严苛是贰个,不然会报语法错误。在行使的时候大家是透过o.r来调用getter方法,而setter方法的调用时如下,o.r
= 二;

当大家从没定义setter方法的时候,使用对象调用setter方法的时候尽管不会报出错误,可是对象中从不任何变动。而当大家在概念对象的时候从不概念getter方法的时候,在大家调用那一性质的时候,将会取得undefined。

 

2:js对象属性操作

1.拜访属性。

  对象属性的造访1般是由此obj.attr的格局来做客的,或许是obj[attr]的秘籍来举行操作,1般景观之下那样都以足以行的通的,不过但大家的是性质名称是1对例外字段的额时候就要小心了,例如关键字可能保留字段,那是后我们要透过中括号的款型来做客才方可成功,当然这一点在ECMAScript5中的已经济体改变了,但是在大家平日编写的时候依然要小心变量的命名。对于保存字段尽量不要采取。

  属性访问的时候,当对象存在而目的中尚无这1本性的时候,就算程序中访问了近期的习性的话大家,js的解析器将会重回undefined的数值,可是即便当前亟待拜访的靶子是不存在的,这年js就会回来叁个类别错误。

二.属性赋值。

  我们能够透过赋值运算来为属性中可写的性质赋值,当访问的目的存在,可是表达式中的属性不设有时候,则会回来三个体系错误。如下

ECMAScript 8

1 var obj = {
2     
3     this.name = "Arvin";
4 
5 };
6 
7 obj.lastName = "Huang";  //这是当前的额内容将会爆出一个类型错误。

ECMAScript 9

  但是即便说null和undefined在js中是明知故犯的靶子,可是大家也不得以为其安装属性,因为他们皆以只读的。而上一段代码中的原理其实就是其一。obj.lastName不存在,所以js重返的额是undefined对象,之后再总结赋值运算所以会报错。

  当然有局地目的属性纵然无法赋值但是大家对其举办赋值的时候依然不会报错,例如如下代码:

1 Object.prototype = 0;//复制失败但是并不会报错。object原名没有被修改。

 在ECMAScript中的严谨形式下边已经取得了修复。

  大家对于目的中的属性赋值出错的情事会有如下的总计。

  • O中的属性是只读的时候,我们对此当下质量是唯有访问权限而并未有复制权限的。
  • O中的某艺术性为后续属性的时候,大家是不可能对其展开赋值的。
  • O中不设有自有属性P,没有继续Setter方法的时候,并且O对象是不行增添的,则当前的目的是不足定义新的属性的。

三.属性删除:

  delete运算符能够去除对象中的属性。那里先讲一下delete运算符的情节。

  delete:1元运算符,用于删除对象和数组中的属性的,单它也无非是去除贰个值,并不会回到删除的内容。

ECMAScript 10

1 var o = {x:1, y:2};//定义了一个对象
2 delete o.x;
3 "x" in o;  //这里将会得到false值。
4 
5 var a = [1,2,3];
6 delete a[1];
7 2 in a; //元素2已经不再数组中了。
8 
9 a.length == 3 //这里将会显示为true,虽然删除了属性但是,留下了一个占位,所以数组长度没有变化。

ECMAScript 11

ECMAScript 12那是在chrome中运营的结果,大家可以瞥见,删除属性之后实际只是因素自个儿与目的的关系被断开了,不过实际上数组中的内容数量如故尚未变动的,可是并未数值,所以通过undefined来开始展览填写。

delete操作数供给时贰个左值(对象的习性,变量),如若不是的话将会不做其余操作重回true。如下图:

ECMAScript 13图表中凸现,重回的值是true,可是7并不是一个左值。

当然也有1些delete没有办法删除的左值。

ECMAScript 14总之,delete是未曾主意删除用var关键字定义的变量是无法去除的。在delete删除成分失利的时候会回到四个false值。当然我们应用群居变量定义的性子也是能够通过delete对象来删除的,因为全局对象也是目的呢。

  好接下去回归正题。对象通过delete实际上正是断开当前的对象和总体性之间的关联。当大家删除了质量之后还要寻找那一天性的时候,大家会获取的值是undefined那个值。当然delete只好删除自有总体性,对于一连属性delete是从来不效应的。即使想删除继承属性的话,直接在对原型对象属性举办删减不就好了。。还有一些,当对象的属性是不足配置的时候也是不删除的(可是当对象是不可配置的,可是其属性是足以布置的时候,如故得以去除的。对象的特色内容请看后文。)

  当然在用delete的时候照旧要注意的应为有些情状下将会现出有的标题。如下代码。

1 var o= {x:1, y:2};
2 var b = o.x;
3 delete o.x;
4 //这个时候b实际上还是只想之前的x的内容的,这种情况很容易导致内存泄漏的额问题。

 

肆.检查测试属性:

  大家常常要一口咬住不放某壹天质量是或不是留存于某三个对象中。今年大家能够通过in运算符,hasOwnProperty()方法只怕propertylsEnumerable()方法来进行判断。

  首先大家来讲一下IN运算符的内容:in操作符是三个2元操作符,其右边的额数值是字符串或然是能够转账为字符串的,左边的始末是指标。判断的此时此刻的属性是否存在于对象中。

ECMAScript 15

1 var point = {x:1};
2 
3 "x" in point; //这一个表达式最后返回的将会是true。
4 "toString" in point; //由于toString是继承方法,所以也是返回true.
5 "z" in point; //这一表达式最后返回false,因为point对象中没有z属性.
6 
7 //数组可以通过索引来判断当前的数组中是否有相应的数据。

ECMAScript 16

故此大家能够透过动用in操作符来判断当前的属性是还是不是存在与某壹对象中的。并且即使是延续属性,也是足以测试的。

  第一种检查实验的不二等秘书诀是hasOwnProperty()方法。代码如下:

1 var o ={x:1};
2 
3 o.hasOwnProperty("x"); //true:o有这一属性,
4 o.hasOwnProperty("y"); //false;
5 o.hasOwnProperty("toString"); //false

由此大家得以领略,hasOwnProperty方法只好测试当前品质是还是不是指标的自有总体性。

  第三种检查测试方法是用propertylsEnumerable()方法。只有当当前的个性是自有质量,并且是可枚举的的时候,这一主意才会回到true。

 

五.枚举属性:

  遍历属性将会是进场要用到的剧情。

  • for/in循环遍历当前的目的的剧情是一种很宽泛的伎俩。其得以遍历对象中的全体的可枚举属性,包括如今指标的自有总体性和延续属性。
  • Object.key()方法,枚举属性名称的函数,他回到的是一个数组,在那之中存在的是指标中的可枚举属性名称组成。
  • Object.getOwnPropertyNames()方法,其回来的额也是数组,可是是兼备的自有总体性名称的数组。

 

三:js属性性情:

  属性的特征其实就是值当前的性能是或不是能够写可以读等等。即外表对象对于属性操作的权力。

  当前的js一般的品质都以有四中品质。分别是:数值属性value,可读属性writable,可枚举属性enumerable,和可安插属性configurable。可是由于目的中设有一类尤其的天性存取器属性,所以对于存取器属性的值实际上是有点分裂的,他有投机的专门的品质个性包括,读取(get),写入(set),可枚举和可配置。为了兑现那1对象属性的讲述,js中定义了一个属性描述符对象。并且能够由此Object.getOwnPropertyDescriptor()方法来取得有些对象中的特定属性的叙述符。当然当前函数只可以获得对象自有总体性的叙说,假如要获取继承属性的讲述符的话,需求运用Object.getPrototypeOf();

  当然我们能够运用Object.defineProperty方法实行对象内容的展开相关的编写,如下

ECMAScript 17

1 Object.defineProperty({},"x", {value:1, writable:true, enumerable:true, configurable:true});
2 //这是将返回一个对象,并且其中设定了一个可读写,枚举和配置的属性x
3 
4 //当然如果要修改的对象本身其中就有一个这一属性,然后想通过这一方法配置的话。也是可以的。
5 
6 //特性对象中的内容可以不用写全,当添加属性的时候未写明的内容将会直接设置成为false或是undefined。而在修改属性的时候未写明的内容将不会有任何改变。

ECMAScript 18

当然大家也能够用Object.defineProperties()来开始展览对个属性的改动和添加,那是大家须要三个对应列表。如下代码

1 Object.defineProperties({}, {
2     x:{value:1, writable:true},
3     y:{value:2, writable:true},
4     ......
5 });

  当我们在概念1个对成分的属性的时候,大家要留心下面多个章程在少数意况之下是会报错误的,情况如下

  • 指标是不可增加的,所以我们只可以对原有的自有总体性进行编写制定,不过不可以添加新的性质。
  • 假诺属性是不足配置的,则不得以修改他的可配置性和可枚举性。
  • 储存器属性是不可配置的,则不得以修改他的setter和getter属性,并且不可能改成多少属性。
  • 数量属性不可配置则不能够改改为存款和储蓄器属性。
  • 数量属性是不行配置处境下,其可写属性不可改false为true,然而足以修改true为false。
  • 假诺数据属性是不可配置不行写,不能够改改其值,但是可配备不行写,则能够修改。

ECMAScript 19

var obj = {
    x:1, 
    get y(){return x;},
    set y(value){x = value;}
};

console.log(""+obj.hasOwnProperty("y"));
console.log(Object.getOwnPropertyNames(obj).toString());

Object.defineProperty(obj,"x",{value:1, writable:true, enumerable:false, configurable:true});//修改当前属性为不可枚举的
console.log(Object.getOwnPropertyNames(obj).toString());
console.log(""+obj.hasOwnProperty("x"));
console.log(""+obj.propertyIsEnumerable("x"));
obj.x = 2;
console.log(obj.x);

Object.defineProperty(obj,"x",{value:1, writable:false, enumerable:true, configurable:true});//修改当前属性为不可写的
console.log(Object.getOwnPropertyNames(obj).toString());
console.log(""+obj.hasOwnProperty("x"));
obj.x = 2;
console.log(obj.x);

Object.defineProperty(obj,"x",{value:1, writable:true, enumerable:true, configurable:false});//修改当前属性为不可配置的
console.log(Object.getOwnPropertyNames(obj).toString());
console.log(""+obj.hasOwnProperty("x"));
obj.x = 3;
console.log(obj.x);

Object.defineProperty(obj,"x",{value:1, writable:false, enumerable:false, configurable:true});//测试不可配置属性是否可以改变属性特性
console.log(Object.getOwnPropertyNames(obj).toString());
console.log(""+obj.hasOwnProperty("x"));
obj.x = 3;
console.log(obj.x);

ECMAScript 20

 

运维结果如下:

4:js对象方法。

  我们那边根本表达的将会是js的Object.prototype里面包车型大巴原生的不2秘籍。

  1、toString()方法,是我们常用到的3个情势,当大家要将指标转换为值的时候,都会调用这么三个方法,然则其落到实处,实际上只是回来了部分指标的音信。例如:

1 var s = {x:1, y:1}.toString()
2 //这里返回的内容是[Object, Object]

  当然在诸多的内置对象中toString方法其实是被重写了的,例如,array(数组)对象中,大家是童toString方法的话,是吧当前的额数组中的内容以逗号隔开分离的款型来回到字符串的。函数调用toString方法的时候,是回到函数的源代码。还有Data对象是toString方法重回的是近年来时刻星系字符串,等等。

  二、toLocaleString方法和toString方法是左近的,只是重回的是本地的字符串,实际上就是依照局地地点的用户选择习惯来定义的回到内容。

  三、toJSON()方法,实际上在Object.prototype中是未曾那一办法的。大家常用的多的是在Date对象中利用,当供给取稳当前目的的连串化的时候调用他它怎会赢妥善前指标的连串化。

  4.valueOf()方法,类似于toString()方法,实际上在js唯有在要啊当前的对象转换为费字符串的景色之下才会调用那壹办法。一般的目的调用那壹主意的时候,重返的数值,实际上就是方今指标的内容,当然内置对象也有改观了这一艺术的达成的。例如Date.valueOf(),重返的正是从一96九年八月十八日到最近的阿秒数。

 

5:js对象的特征。

  一、原型属性:原型属性实际上正是时下的对象继承自哪多个目标,当前目标继承了原型对象中的方法和个性,所以大家誉为对象的原型属性,当然也足以称作对象的原型。当然大家也有二个办法测试某一指标是或不是是继承与另一指标,使用isPrototypeOf()方法来举行判断。

 

  2、类的性质:其实其自己是多少个字符串来着,用以代表对象的体系,上文中的提到的toString方法能够取得类的属性。当然由于toString在无数的嵌入对象中有重写,所以党大家调用toString的主意的时候最佳使用的如下封装方法。

ECMAScript 21

1 function classof(o){
2     if(o === null){
3         return "Null";
4     }
5     if( o === undefined){
6         return "Undefined";
7     }
8     return Object.prototype.toString.call(o).slice(8, -1);
9 }

ECMAScript 22

 

  叁、可增添性:对象的可扩展性表示的是但钱的靶子是或不是是能够扩张的,宿主对象的可扩充性是有但钱的额js的斯特林发动机来进展定义的,全数的额内置对象都以足以增加的,除非大家把其转化成为不可扩大的对象,Object.esExtensible()能够用来拓展判定的眼下的目的是还是不是是能够扩充到的。Object.preventExtensions()方法设置当前的落到实处格式不得以增加的内容。当大家把对象设置成为不可扩大之后,大家就不得以在准换当前的始末。实际上上述的章程只是对于当前目的的即兴空间来定义的,所以党大家改变源性对象的时候当前的靶子中实际上还是会有肯定的扭转的。当然还有一对别样的格局是能够来防止对象的面临外来的搅和的。Object.seal()其实和事先的preventExtensible()方法也许挺像的,除了将但前的目的设置成为不可设置的,同事呢其负有的额属性也同时设置成为不可设置的。还有贰个函数更绝,Object.freeze()方法不但把对象的品质和自个儿设置成为不可配置的,同事也安装为不可写的情景,所以所设置达成之后全体就2头读对象。

 

  4.连串化对象:实际上正是指当前的目的转化为字符串,当然也是能够苏醒的。类别化当前的靶子实际正是经过JSON来进展操作的。个中将Object转化成为json字符串的法子是,JSON.stringify(),个中的参数是急需系列化的靶子。而JSON.parse()则是反系列化,但其实那样得出的目的是系列化的深拷贝。当然JSON只是js的一个子集,援救对象,数组,字符串,无穷大数字,true,false,null。NaN,infinity等等那1类数据在体系化的时候都会计统计1转化成为null,而Date的数额在种类化的时候是会直接转换到为ISO格式的日期字符串,就就好像于Date.toJSON()方法1致的。