1.什么是对象?
由属性组成的无序集合(n个键值对)。
2.数据类型分两类:
原始类型:undefined,null,boolean,string,number
object类型:function,array,date,regexp
3.对象结构:
- 对象属性;
- 属性特征;
- writable是否可写的
- enumerable是否可枚举的
- configurable是否可重置的
- getter ,setter
- proto对象的原型;
- 指向另外一个对象,本对象属性继承自它的原型对像
- extensible对象的扩展标记;
- 是否允许向该对象添加新属性
4.创建对象&原型链(查找某个属性或方法根据原型链自下向上):
I.对象直接量:var obj={} ;
- obj.prototype-->Object.prototype-->null(原型链末端)
II.new函数构造器: var obj = new Foo();
- 新创建的对象的原型指向构造器的原型;
- obj.prototype--->Foo.prototype-->Object.prototype-->null
III.var obj = Object.create({x:1});
- Object.create会返回一个新对象,并且该对象会执行传入的那个参数对象
- obj.prototype--->{x:1}.prototype-->Object.prototype-->null
V.var obj = Object.create(null);
- obj.prototype=null//>obj.prototype-->null
5.对象的proto的内置属性
- JS在创建对象(不论是普通对象还是函数对象)的时候,都有一个叫做proto的内置属性,用于指向创建它的函数对象的原型对象prototype。
var zjh = new person(‘zhangjiahao’);
zjh.getName(); //zhangjiahao
以上面的例子为例:
console.log(zjh.__proto__ === person.prototype) //true
- person.prototype对象也有proto属性,它指向创建它的函数对象(Object)的prototype
console.log(person.prototype.__proto__ === Object.prototype) //true
- Object.prototype对象也有proto属性,但它比较特殊,为null
console.log(Object.prototype.__proto__) //null
- 我们把这个有proto串起来的直到Object.prototype.proto为null的链叫做原型链。
6.属性操作
6.1. 读写对象属性
- obj.x / obj["x"]
6.2. 删除属性
- delete只能删除自有属性
delete obj.z//true
delete obj['z']//true
6.3. 获取某个对象某个属性的描述对象
- var decriptor=Object.getOwnPropertyDescriptor(Object,'prototype');
//{value: {…}, writable: false, enumerable: false, configurable: false}
6.4. 检测属性归属
- 'z' in obj //true可以便利自有属性以及继承属性
- obj.hasOwnProperty('z'); //true 查找自有属性
6.5. 枚举属性
- obj.propertyIsEnumerable('legs');//true是否可以枚举
- for in 所遍历出来属性就是枚举性
6.6. 自定义属性
- 注意:通过对象设置的属性默认属性描述都是true,而defineProperty创建的属性默认是false;
Object.defineProperty(cat,'price',{enumerable:false,value:1000}); cat.hasOwnProperty('price')//true cat.propertyIsEnumerable('price')//false
6.7. 实例理解
- 遍历可枚举属性:
var o = {x:1,y:2,z:3}; var key; for (key in o){ console.log(key);//x,y,z }
- 遍历继承属性:
var obj = Object.create(o); obj.a = 4; var key; for (key in obj){ console.log(key);//a,x,y,z }
- 仅遍历自有属性:
var obj = Object.create(o); obj.a = 4; var key; for (key in obj){ if(obj.hasOwnProperty(key)){ console.log(key);//a } }
6.8. 另外一种读写属性的方式(getter/setter方法):
var man = {
name: 'wangjie',
weibo: '@evrygo',
get age() {
return new Date().getFullYear() - 1992;
},
set age(val) {
console.log("Age can't be set to" + val);
}
}
//访问age属性,就去调用getter方法
console.log(man.age); //27
//设置属性,就去调用setter方法
man.age = 100; //Age can't be set to 100
改进:
var man = {
name: 'wangjie',
weibo: '@evrygo',
$age: null, //属性名前面加$ ,表示这个变量是私有
get age() {
if (this.$age == undefined) { //判断 $age是null或者undefined
return new Date().getFullYear() - 1991;
} else {
return this.$age;
}
},
set age(val) {
val = +val; //va前面加一个一元操作符,为了得到数字;
if (!isNaN(val) && val > 0 && val < 150) { //val不是NaN并且大于0小于150
this.$age = +val;
} else {
throw new Eroor('Incorrect val = ' + val);
}
}
}
6.9. 属性操作实例
- 注意:
给对象属性赋值,如果这个属性不是getter方法,赋值可以成功;
但是属性是getter或者setter方法,就赋值不成功。
function foo() {} //创建一个空的函数对象
//给它的prototype对象添加属性z,并给它一个getter方法
Object.defineProperty(foo.prototype, 'z', {
get: function () {
return 1;
}
});
//利用它创建一个对象
var obj = new foo();
obj.prototype-- - > foo.prototype-- - > 后续
obj.z; //1
obj.z = 10;
obj.z; //still 1
- 如何给属性是getter或者setter方法,还要在obj这个对象上将这个属性赋值
Object.defineProperty(obj, 'z', {
value: 100,
configurable: true
});
obj.z; //100;
delete obj.z;
obj.z; //back to 1
- 总结实例
var o = {};
Object.defineProperty(o, 'x', {value: 1}); //writable=false,configurable=false;
var obj = Object.create(o);
obj.x; //1
obj.x = 200; //writable=false
obj.x; //still 1
Object.defineProperty(o, 'x', {
writable: true,
configurable: true,
value: 100
});
obj.x; //100
obj.x = 500;
obj.x; //500
6.10. 属性描述符操作
- 属性描述符控制某些属性操作权限:
configurable:能否使用delete、能否修改属性描述符、或能否修改访问器属性、能否通过delete删除属性从而重新定义属性(Object.defineProperty)
enumerable:对象属性是否可通过for-in循环
writable:对象属性是否可修改
value:对象属性的默认值 - 属性特性获取以及设置
- 显示某个对象的某一个属性的所有属性特性:
Object.getOwnPropertyDescriptor({ pro: true }, 'pro'); Object{value:"true,writable:true,enumarable:true,configurable:truye"}
- 注意:configurable控制这其他属性标签是否可改,还有控制属性是否delete
实例1: var person = {}; Object.defineProperty(person, 'name', { configurable: false, writable: false, enumarable: true, value: "evrygo" }); person.name //evrygo person.name = 1; person.name; //still evrygo delete person.name; //false 实例2: Object.defineProperty(person, 'type', { configurable: true, writable: true, enumarable: false, value: "Object" }); //获取对象上所有属性名 Object.keys(person); //["name"] //因为type为enumarable: false
- 显示某个对象的某一个属性的所有属性特性:
- 给某个对象的设置多个属性的属性特性
Object.defineProperties(person, { //没有写的属性特性默认为false title: { value: 'fe', enumarable: true }, corp: { value: 'ba', enumarable: true }, salary: { value: 50000, enumarable: true, writable: true }, luck: { get: function () { return Math.random() > 0.5 ? 'good' : 'bad'; } }, promote: { set: function (level) { this.salary *= (1 + level * 0.1); } } }); person.salary; //50000 person.promote = 2; person.salary; //60000