无序属性的集合,其属性可以包含基本值,对象,或者函数。可以将对象想象成散列表:键值对,其中值可以是数据或者函数。ECMAScript中的对象其实就是一组数据(属性)和功能(方法)的集合。
一、Object原型属性及方法(原型方法,实例可以调用的方法)
1.每一个
构造函数
都有一个原型属性prototype
指向他的原型对象
;
2.每一个原型对象
中都有一个constructor属性
指向他的构造函数
;
3.每一个实例
都有一个属性叫__proto__
指向原型对象
;
4.写在构造函数内的属性和方法只有构造函数本身可以调用
,原型对象与实例都不可以调用;
5.写在·原型对象的属性和方法·称为实例属性和实例方法,既可以·通过实例调用
,也可以通过原型对象调用
;
6.构造函数
可以创建多个实例
,每个实例都有自己的属性和方法,实例也可以继承原型对象中的属性和方法
;
注:图中数字编号对应上述文字描述
- 使用构造函数创建实例对象
var obj1 = new Object()
- 调用原型对象中继承的方法
console.log(obj.toString());//[object Object]
console.log(obj.__proto__.toString());//[object Object]
- 实例中的__proto__ 指向 原型对象Object.prototype
console.log(Object.prototype); // [Object: null prototype] {}
console.log(obj.__proto__);//[Object: null prototype] {}
console.log(obj.__proto__ === Object.prototype); //true
- 原型对象中的constructor属性 原型对象中的constructor属性指向构造函数
console.log(Object); //[Function: Object]
console.log(Object.prototype.constructor); //[Function: Object]
console.log(Object.prototype.constructor === Object);//true
二、Object.prototype原型对象中的常用方法
constructor
保存用户创建当前对象的函数,与原型对象对应的构造函数hasOwnProperty(propertyName)
检查给定的属性名是否是对象的自有属性propertyIsEnumerable(propertyName)
检查给定的属性在当前对象实例中是否可以枚举valueOf()
返回值为该对象的原始值toLocaleString()
返回对象的字符串表示,该字符串与执行环境的地区对应toString()
返回对象的字符串表示isPrototypeOf(object)
检查传入的对象的原型, a.isPrototypeOf(b) 如果a是b的原型,则返回true。如果b不是对象,或者a不是b的原型,则返回false。
三、对象属性检测
检测一个属性是否属于某个对象。常用的方式主要有3种:
1.in(不是原型方法)
检测某属性是否是某对象的自有属性或者是继承属性
var obj = {
name: 'zs',
age: 18,
}
//in运算符的左侧为属性名称,右侧为对象
console.log('name' in obj); //true
console.log('gender' in obj); //false
//如果用in判断一个属性存在,这个属性不一定是obj的,它可能是obj继承得到的,如:
console.log('toString' in obj); // true
因为toString定义在object对象中,而所有对象最终都会在原型链上指向object,所以obj也拥有toString属性。
2.Object.prototype.hasOwnProperty()(原型方法)
检测给定的属性是否是对象的自有属性
,对于继承属性将返回false
var obj = {
name: 'zs',
age: 18,
}
console.log(obj.hasOwnProperty('name')); //true
console.log(obj.hasOwnProperty('toString')); //false,toString为继承属性
console.log(obj.hasOwnProperty('gender')); //false
3.Object.prototype.propertyIsEnumerable()
propertyIsEnumerable()是hasOwnProperty()的增强版,除了是自身属性外,还要求是可枚举属性,即我们创建的属性,如果enumerable设置为false则显示false。
var obj = {
name: 'zhangsan',
age: 18
}
console.log(obj.propertyIsEnumerable('name')); //true
console.log(obj.propertyIsEnumerable('toString')); //false,不可枚举
四、对象定义属性
ECMAScript中有两种属性:
数据属性、访问器属性
。这两种属性用于设置属性的高级属性,例如该属性是否可以删除,是否可以读写,是否可以遍历,并且可以通过setter,getter来监听数据的改变。
1. 数据属性
相当于给当前对象定义了一个公共属性,访问修改直接返回value值;
属性默认特性:
-
configurable
表示是否通过delete删除属性从而重新定义属性,能否修改属性的特性,或者能否把属性修改为访问器属性(属性直接定义在对象中,默认为true)。 当为false时,不能重新定义不能使用delete删除。 -
enumerable
表示能否通过循环返回属性。(属性直接定义在对象中,默认为true) -
writable
表示能否修改属性的值。(属性直接定义在对象中,默认为true) -
value
属性的数据值 name:zs
let obj={
name:'zs',
age:18
}
//name: {
// value: 'age',
// writable: true,
// enumerable: true,
// configurable: true
},
// age: { value: 18, writable:true, enumerable: true, configurable:true },
2. 访问器属性
可以控制访问或修改这个属性的具体行为
访问器属性跟数据属性大同小异,就是删去了value和writable属性,加入了get和set属性。
注意:访问器属性不能直接定义,要通过Object.defineProperty()这个方法来定义。
Object.defineProperty()使用方法可以查看第五点Object构造函数中的常用方法
-
configurable
表示是否通过delete删除属性从而重新定义属性,能否修改属性的特性,或者能否把属性修改为访问器属性。 当为false时,不能重新定义不能使用delete删除。默认为false -
enumerable
表示能否通过循环返回属性,默认为false。(属性直接定义在对象中,默认为true) -
get
在读取属性时调用的函数,默认值为undefined -
set
在写入属性时调用的函数,默认值为undefined
// 创建一个对象
var person = {
// 内部属性
_birthday: 2000,
age: 1
}
// 新增一个访问器属性
Object.defineProperty(person, 'birthday', {
enumerable: true,
get: function() {
return this._birthday
},
set: function(newValue) {
if (newValue !== this._birthday) {
this._birthday = newValue
this.age++
}
}
});
// 测试访问属性中的get,set方法
console.log(person.birthday);//2000
person.birthday = 2021;
console.log(person.birthday);//2021
// 问器属性可以通过Object.getOwnPropertyDescriptor()查询
console.log(Object.getOwnPropertyDescriptor(person, 'birthday'));
// {
// get: [Function: get],
// set: [Function: set],
// enumerable: true,
// configurable: false
// }
注意: 当我们创建一个对象并且为对象设置好属性及其值的时候,该属性默认特性Configurable、Enumerable、Writable默认都为true,value为该属性的值,当我们使用defineProperty为对象添加值,并不设置属性默认特性时,默认都为false。
五、Object构造函数中的常用方法
1.Object.defineProperty()
功能:
定义新属性或修改原有的属性。
语法:
Object.defineProperty(obj, prop, descriptor)
参数说明:
- obj:必需。目标对象
- prop:必需。需定义或修改的属性的名字
- descriptor:必需。目标属性所拥有的特性
注意:使用该方法创建的对象属性,该属性默认特性Configurable、Enumerable、Writable默认都为false;
Object.defineProperty(obj,'name',{
configurable:true,
enumerable:true,
writable:true,
value:'zs'
})
console.log(obj.name);
2.Object.defineProperties()
功能:
一次性定义多个属性
语法:
Object.defineProperties(obj, props)
参数说明:
- obj:必需。目标对象
- props:该对象的一个或多个键值对定义了将要为对象添加或修改的属性的具体配置
返回值:
传入函数的对象。即第一个参数obj;
var obj = new Object();
Object.defineProperties(obj, {
name: {
value: 'zs',
configurable: false,
writable: true,
},
age: {
value: 18,
configurable: true
}
})
console.log(obj.name, obj.age) // zhangsan, 18
3.Object.getOwnPropertyDescriptor()
功能:
该方法返回指定对象上一个自有属性对应的属性描述符。(自有属性指的是直接赋予该对象的属性,不需要从原型链上进行查找的属性)
语法:
Object.getOwnPropertyDescriptor(obj, prop)
参数说明:
1.obj: 需要查找的目标对象
2.prop: 目标对象内属性名称
var person = {
name: 'zs',
age: 18
}
var desc = Object.getOwnPropertyDescriptor(person, 'name');
console.log(desc) 结果如下
// {
// configurable: true,
// enumerable: true,
// writable: true,
// value: "zs"
// }
4.Object. getOwnPropertyDescriptors()
功能:
所指定对象的所有自身属性的描述符,如果没有任何自身属性,则返回空对象。
语法:
Object.getOwnPropertyDescriptors(obj)
参数说明:
obj: 需要查找的目标对象
var person = {
name: 'zs',
age: 18
}
var desc = Object.getOwnPropertyDescriptors(person);
console.log(desc)
// {
// name: { value: 'zs', writable: true, enumerable: true, configurable: true },
// age: { value: 18, writable: true, enumerable: true, configurable: true }
// }