js object(对象)

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

Object(对象)是当装有的编程语言中都怪要的一个概念,对于事物我们好管他们作是一个靶,而每一个东西都生谈得来之代表的性能和对有一样音讯作出的呼应的操作。而这些事物就是改为了物的性能和章程。

  在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中的目标就是一个坐键值对形式储存属性之一个成团,每一个特性有一个一定的名称,并和名称相对应之值。其实这种涉及是起一个专有名称的,我们得称之为映射,当然对于目标的话,除了可经过这种办法来维持打生性,还好透过继承的计来取得继承属性。这种办法我们叫“原型式继承”。

 

连下我们拿于js对象的性,属性特性,方法和对象特性等多只地方来修目标的概念。

1.js目标创建和目标属性。

2.js对象属性操作。

  • 走访属性
  • 性赋值
  • 去除属性
  • 检测属性
  • 枚举属性

3.js对象属性特性。

4.js靶方法。

5.js对象特性。

 

一律: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关键字来创造一个颇具独立内存区域和指向原型的指针的靶子。当我们使用的new的时刻,js解析器会分配一块内存空间,用以存放时之目标的由来总体性。之后解析器会为这无异目标一个_proto_属性指向的原型对象内容。

 

还有同栽办法我们叫对象直接量申明的主意,代码如下:

ECMAScript 5

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

ECMAScript 6

目标直接量就是直通过花括号包裹的键值对之款式来定义当前目标的。每半只价内的经过逗号来开展分。键和价值期间通过冒号来分。放解析器读取到当前底始末之时节会活动的别一个目标的情节并把目前的对象存储于时下及下文中。

 

再有平等种植对象创建的法子是采取Object.create()方法,这同一主意是ECMAScript5遭遇定义的一个情节,它是一个静态方法,其以方法如下。

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

这等同措施传入的参数是一个靶,并且这同图的对象将会见当新的靶子的原型是。

 

连下去我们来拘禁无异圈性。

当我们在chrome的命令台中运作第一段落示例代码的早晚咱们好观看如下的内容。

ECMAScript 7可见,当我们于构造函数中一直用this指针(指代即的对象)添加属性,这时,其实我们的设置的特性是当下的对象特有的属性,独属于即之目标的,这样的性称之为由出总体性。而以咱们定义构造函数的时段,我们呢构造函数的prototype属性(指向原型对象),这时我们定义了prototype的情跟方法。当使用new关键字来展开对象的布局之当儿,我们所组织的靶子实际是连续了及时等同原型对象的情的,所以我们得再次对象的_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方法的时候表示马上等同特性是只是写的,存取其属性实在ECMAScript5受到才有定义之,实际上是把性能通过函数的道开展与外的数交互的。从而令属性值本身不得以一直开展配置或者获取。

存取器属性的写法就使上面代码书写的一样,get关键字空格之后跟属性名称作为函数的名,set方法及get方法是一致编写的,只是碰头传播参数,并且参数的个数严格是一个,否则会报语法错误。在运用的下我们是透过o.r来调用getter方法,而setter方法的调用时如下,o.r
= 2;

当我们从来不定义setter方法的早晚,使用对象调用setter方法的当儿虽然未见面报发出左,但是对象吃从未外变动。而当我们当概念对象的上从不概念getter方法的下,在我们调用这同性之时段,将会见得到undefined。

 

仲:js对象属性操作

1.走访属性。

  对象属性之访一般是透过obj.attr的道来访问的,或者是obj[attr]的方式来拓展操作,一般情况之下这样还是足以推行之交接之,但是可我们的凡性质名称是一些特殊字段的额时候就要小心了,例如关键字或者保留字段,这是后我们只要经过中括号的形式来访问才得成功,当然这点当ECMAScript5挨的既转了,但是于咱们平常编写的时候还是如专注变量的命名。对于保留字段尽量不要用。

  属性访问的时光,当目标存在如目标被并未当即无异于属性之上,如果程序中访问了时的性质之口舌我们,js的解析器将会晤返回undefined的数值,但是若手上需看的对象是勿有的,这个上js就会见回一个种错误。

2.属性赋值。

  我们得以经过赋值运算来吧性被不过写的属性赋值,当访问的目标存在,但是表达式中之性不设有上,则会返回一个种类错误。如下

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对象是不行扩展的,则当前底靶子是不可定义新的性质之。

3.属性删除:

  delete运算符可以去除对象吃之属性。这里先谈一下delete运算符的情。

  delete:一冠运算符,用于去对象与数组中之习性之,单它也单独是去一个值,并无会见返回去的内容。

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并无是一个左值。

当为时有发生部分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的内容的,这种情况很容易导致内存泄漏的额问题。

 

4.检测属性:

  我们常常要看清有一个性能是否留存被某个一个对象吃。这个时节咱们可以通过in运算符,hasOwnProperty()方法可能propertylsEnumerable()方法来开展判定。

  首先我们来讲一下IN运算符的情:in操作符是一个二元操作符,其左侧的额数值是字符串或者是好转化为字符串的,右边的情是目标。判断的手上底性是免是在被对象吃。

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。

 

5.枚举属性:

  举历属性将会晤是进场要因此到的情节。

  • for/in循环遍历当前的对象的内容是一致种异常广泛的手段。其得以遍历对象吃的备的而是枚举属性,包括目前目标的由发生总体性和继承属性。
  • Object.key()方法,枚举属性名称的函数,他返的凡一个数组,其中在的是目标中的但枚举属性名称组成。
  • Object.getOwnPropertyNames()方法,其归来的额头为是数组,但是是负有的自出性名称的数组。

 

老三:js属性特性:

  属性的特色其实就是是价值时底性是否可以描绘得读等等。即外表对象对性操作的权力。

  当前的js一般的性能都是起4丁性能。分别是:数值属性value,可读属性writable,可枚举属性enumerable,和而配置属性configurable。但是出于目标中有一样像样特别之属性存取器属性,所以对存取器属性的价实际上是发出接触不同的,他生投机的专门之习性特性包括,读取(get),写副(set),可枚举和而配置。为了兑现即无异对象属性的描述,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 });

  当我们以概念一个针对性素的特性的下,我们设留心点两只方法在好几情况之下是碰头报错误的,情况如下

  • 目标是不足扩展的,所以我们只好对原有的打发生性进行编辑,但是未得以互补加新的性。
  • 万一属性是不行配置的,则不可以修改外的只是配置性和而枚举性。
  • 仓储器属性是不足配置的,则免可以修改外的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

 

运转结果如下:

季:js对象方法。

  我们这里主要说明的将会晤是js的Object.prototype里面的原生的方式。

  1、toString()方法,是我们经常因此到的一个办法,当我们若用对象转换为值的时候,都见面调用这么一个方,但是那个落实,实际上只有是回去了有靶的音。例如:

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

  当然在重重之坐对象中toString方法其实是深受再次写了的,例如,array(数组)对象被,我们是童toString方法吧,是吧时的额数组中之始末因逗号隔开的款型来回到字符串的。函数调用toString方法的时光,是回去函数的源代码。还有Data对象是toString方法返回的凡目前时星系字符串,等等。

  2、toLocaleString方法以及toString方法是相近的,只是返回的是地方的字符串,实际上就是冲一些地面的用户采取习惯来定义的回内容。

  3、toJSON()方法,实际上以Object.prototype中是没马上同一计的。我们经常因此的基本上的凡当Date对象被采用,当得取当前目标的序列化的当儿调用他她怎么会得到当前目标的序列化。

  4.valueOf()方法,类似于toString()方法,实际上在js只有以使吧时的对象转换为费字符串的情形之下才见面调用这无异于方式。一般的对象调用这同方法的上,返回的数值,实际上就是时目标的始末,当然内置对象呢产生变动了当时无异术的兑现之。例如Date.valueOf(),返回的就是是打1970年1月1日届本之毫秒数。

 

五:js对象的性状。

  1、原型属性:原型属性实际上就是当前底靶子继承自哪一个对象,当前目标继承了原型对象中之法与总体性,所以我们叫对象的原型属性,当然也得以称对象的原型。当然我们吧来一个措施测试某一样目标是不是是延续和另一样靶,使用isPrototypeOf()方法来进行判断。

 

  2、类的性能:其实那本人是一个字符串来在,用以代表对象的品种,上文中之关联的toString方法好取类的特性。当然是因为toString在成千上万的内置对象被来重写ECMAScript,所以党我们调用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

 

  3、可扩展性:对象的但扩展性表示的凡可钱之对象是否是好扩大的,宿主对象的只是扩展性是发可钱的额js的发动机来进行定义之,所有的额内置对象还是得扩大的,除非我们将那转会成不可扩展的目标,Object.esExtensible()可以就此来进行判定的即的对象是不是是足以扩展及之。Object.preventExtensions()方法设置当前底贯彻格式不得以扩展的始末。当我们把对象设置成不可扩展之后,我们就非可以当准换当前的情。实际上上述的不二法门才是对于目前目标的随机空间来定义之,所以党我们转移源性对象的时手上底靶子中实际上要会生出必然的更动之。当然还有有另的法门是可以来避免对象的中外来的扰乱的。Object.seal()其实与事先的preventExtensible()方法要挺像的,除了以只是眼前之目标设置成不可设置的,同事吧其拥有的额属性也又安装成不可设置的。还有一个函数更绝,Object.freeze()方法不仅将目标的性质和自己安装成不可配置的,同事也安为不可写的状态,所以所装完成以后一切就一样只是读对象。

 

  4.序列化对象:实际上即便是因当前之目标转化为字符串,当然为是可过来的。序列化当前的目标实际就是经过JSON来进展操作的。其中将Object转化成为json字符串的点子是,JSON.stringify(),其中的参数是索要序列化的靶子。而JSON.parse()则是倒转序列化,但实质上这样得出的目标是序列化的深拷贝。当然JSON只是js的一个子集,支持对象,数组,字符串,无穷大数字,true,false,null。NaN,infinity等等就等同类似数据以序列化的下还见面统一转化成为null,而Date的多少以序列化的时候是会见直接换成ISO格式的日子字符串,就类似于Date.toJSON()方法同样的。