首页 > 代码库 > JavaScript对象-学习笔记

JavaScript对象-学习笔记

JavaScript权威指南学习笔记,禁止转载!

5、对象

对象的属性是无序的,每个属性都有一个字符串key和值value,

数据属性的标签:writable、enumerable、configurable、value

访问器属性的标签:enumerable、configurable、get、set。get表示属性可读,set表示属性可写。属性前面有下划线表示只能通过对象方法get/set访问的属性,也就是访问器属性。

(1)创建对象

1)字面量var obj={x:1,y:2};

2)new:var obj=new foo(); (obj的proto指向构造函数foo的foo.prototype)

如,function foo(){};

var obj=new foo();

typeof obj;  //"object"

typeof obj.toString;  //"function"(toString方法是obj原型链上Object.prototype上的方法)

注意:若(obj.z; //undefined)不代表obj对象及其原型链上没有属性z,可能有属性z但值是undefined。

3)Object.create(原型)

如,var obj= Object.create({x:1}); 此时{x:1}时obj的原型。

typeof obj.toString;  //"function"

注意:但不是每个对象的原型链上都有Object.prototype,因此不是每个对象都有toString方法,如,var obj= Object.create(null); 此时null是obj的原型,也是原型链的顶端,因此,typeof obj.toString;  //undefined

(2)属性操作

~~属性读:

如, var obj={x:1,y:2};

obj.x;  //1

obj[“x”];  //1(不常用)

var p; for(p in obj){console.log(obj[p]);  }

//1

//2

(这种方法会读出obj原型链上的属性,并且属性的顺序不确定。可以用hasOwnProperty过滤掉原型链上的属性。)

读属性会向原型链上查找。

~~检测属性是否存在:

obj.hasOwnProperty(属性名):判断对象obj自身上是否有该属性,返回true或false。

obj.propertyIsEnumerable(属性名):判断对象obj的该属性是否可枚举。原型链上的属性通常不可枚举。

(3)get/set方法和原型链

如,var obj = {};

Object.defineProperty(obj,‘x‘,{value: 1,writable: false,configurable: false,enumerable: false});

var obj1 = Object.create(obj);

obj1.x = 10;

console.log(obj1.x);   //1

当给对象的属性赋值时(obj1.x = 10;):

如果obj1上有x属性,修改其值。

如果obj1上没有x属性,会向其原型链查找,如果原型链上也没有x属性,那么x属性会被添加到obj1对象上;如果原型链上有x属性,则分三种情况:

a、原型链上x属性writable:true,会在obj1上添加x属性,并屏蔽原型链上的属性,

b、原型链上x属性writable:false,这条赋值语句会被忽略,如果是在严格模式下会报错,所以上述obj1.x还是1,

c、原型链上x有set/get方法,还是走原型链上的set/get方法,而不会给obj1上添加新的x属性。此时如果需要给obj1添加x属性,使用Object.defineProperty(obj1,’z’,{value:10,configurable:true});

MARK!

(4)属性标签

Object.getOwnPeopertyDescriptor(对象名,‘属性名‘):返回一个对象,包含这个属性的所有标签。

Object.defineProperty(对象名,”属性名”,属性的标签)(通过这个方法定义的属性,configurable、enumerable、writable的默认值为false)

如,var b={};

Object.defineProperty(b,‘b‘,{configurable:false,writable:true});

Object.getOwnPropertyDescriptor(b,‘b‘);//Object {value: undefined, writable: true, enumerable: false, configurable: false}

如,var person={};

Object.defineProperties(person,{

salary:{value:50000,writable:true},

promote:{

set:function(level){

this.salary*=1+level*0.1;

}

} //promote结束处

});

//Object {salary: 50000}

salary:50000

set promote:function (level)

__proto__:Object

person.promote=2; //调用set方法传值到函数的参数level

person.salary;  //6000

Object.keys(对象):返回一个数组,包含该对象上的所有可枚举的属性名。

注意:如果writable:false,configurable:true,可以通过Object.defineProperties重新设置属性的value标签来变相地修改属性值;当然writable标签也可以被修改为true。

(5)对象标签

_proto_:原型

class:对象类型

Object.prototype.toString.call() 检测数据类型,包括对象的类型。

注意:Object.prototype.toString.call(new Number(1));  //"[object Number]"

Object.prototype.toString.call(1);  //"[object Number]"

extensible:对象上的属性是否可被添加

Object.isExtensible(obj); 判断对象是否可扩展

Object.preventExtensions(obj); 使对象不可扩展

Object.seal(obj):使对象上属性configurable变为false

Object.isSealed(obj)判断

Object.freeze(obj):使对象上属性configurable和writable都变为false

Object.isFrozen(obj)判断

这些都不影响对象的原型链。

(6)对象序列化JSON

把对象转换为字节序列(数据以二进制序列的形式在网络上传送)的过程

JSON.stringify():将javascript值转换为JSON字符串,

如果属性值是undefined,将不会出现在结果字符串中;如果属性值是NaN或Infinity,会转换成null;如果是Date会转换为UTC时间格式,

如,var obj={x:1, y:true, z:[1,2,3], nullval:null, val:undefined, a:NaN, b:Infinity,c:new Date() };

JSON.stringify(obj);

//"{"x":1,"y":true,"z":[1,2,3],"nullval":null,"a":null,"b":null,"c":"2017-05-20T11:48:28.044Z"}"

序列化自定义

var obj={x:1, y:2, o:{

o1:1, o2:2, toJSON:function(){return this.o1+this.o2; }

}

};

JSON.stringify(obj);

// "{"x":1,"y":2,"o":3}"

JSON.parse():将一个 JSON字符串转换为对象。

如,var str=‘{"x":1,"y":2}‘;

JSON.parse(str);

//Object {x: 1, y: 2}(单引号写在{}外面,每个属性名都必须要双引号,否则会抛出异常Uncaught SyntaxError: Unexpected identifier)

(7)valueOf、toString方法

如,var obj={x:1, y:2};

obj.toString=function(){return this.x+this.y; }

+obj;  //3(+加号操作符强制将对象转换为基本类型)

obj.valueOf=function(){return this.x+this.y+100; }

+obj; //103

“result”+obj; //“result103”

当valueOf和toString方法都存在时,先查找valueOf,如果valueOf返回值为基本类型,以此为准,结束;如果valueOf返回值为对象再查找toString,如果toString返回值也为对象,就会报错。

JavaScript对象-学习笔记