什么是对象
在现实生活中,万物皆为对象,对象是一个具体的事物,看得见摸得着的实物。对象有它的属性,如身高和体重,方法有走路或跑步等;所有人都有这些属性,但是每个人的属性都不尽相同,每个人都拥有这些方法,但是方法被执行的时间都不尽相同。
在JavaScript 中,对象是一组无序的相关属性和方法的集合,所有的事物都是对象,例如字符串、数组、数值、函数等等。
对象是由属性和方法组成
- 属性:事物的特性,在对象中用属性来表示
- 方法:事物的行为,在对象中用方法来表示
创建对象的方法
1. 利用字面量创建对象
var obj = {
name: shangsan, // 利用 :赋值
age: 13, // 属性与属性之间通过","隔开
sex: '男',
sayName:function(){
console.log("my name is ",this.name); // 方法 冒号后面跟的是匿名函数
}
}
// 调用属性的方法 属性名.属性 / 属性名.["属性"]
console.log(obj.name);
console.log(obj{"age"});
// 调用对象的方法
obj.sayName();
2. 利用new Object 创建对象
var obj = new Object();
obj.name = "zhangsan"; // 利用= 赋值
obj.age = 13; // 属性与属性之间用“;”分隔
obj.sex = '男'
obj.sayName = function(){
console.log("my name is",this.name);
}
console.log(obj.name);
console.log(obj{"age"});
obj.sayName();
遍历对象
var obj = {
name: shangsan,
age: 13,
sex: '男',
sayName:function(){
console.log("my name is ",this.name);
}
}
// for in 遍历对象
// for (变量 in 对象)
for (k in obj) {
console.log(k) // k 变量 输出得到属性名
console.log(obj[k]) // 输出得到属性值
console.log(k+"--"+obj[k]); // 输出属性 -- 属性值
}
检测属性
检测一个属性是否属于某个对象
方法1:in
var obj = {
name: 'zhangsan',
age: 13,
sex: '男'
}
// 检测属性是否属于obj这个对象
console.log('name' in obj); // true
console.log('age' in obj); // true
console.log('gender' in obj); // false
// toString不是obj的属性 但检测结果是对的 因为toString是obj继承得到的
// 因为toString定义在object对象中,而所有对象最终都会在原型链上指向object,所以obj也拥有toString属性。
console.log('toString' in obj); // true
方法2:Object.prototype.hasOwnProperty()
检测给定的属性是否是对象的自有属性,对于继承属性将返回false
var obj = {
name: 'zhangsan',
age: 13,
sex: '男'
}
console.log(obj.hasOwnProperty('name')); //true
console.log(obj.hasOwnProperty('age')); //true
console.log(obj.hasOwnProperty('toString')); //false,toString为继承属性
console.log(obj.hasOwnProperty('gender')); //false obj没有这个属性
方法3:Object.prototype.propertyIsEnumerable()
是hasOwnProperty()的增强版,除了是自身属性外,还要求是可枚举(可删除)属性,即我们创建的属性。
var obj = {
name: 'zhangsan',
age: 13,
sex: '男'
}
console.log(obj.propertyIsEnumerable('name')); //true
console.log(obj.propertyIsEnumerable('age')); //true
console.log(obj.propertyIsEnumerable('toString')); //false,不可删除
console.log(obj.propertyIsEnumerable('gender')); //false obj没有的属性
深入理解对象-定义属性
在ECMAScript中有两种属性:数据属性、访问器属性。用于设置属性的的高级属性,例如该属性是否可以配置,是否可以读写,是否可以遍历,并且可以通过setter,getter来监听数据的改变。
数据属性
包含的是一个数据值的位置,在这可以对数据值进行读写
var obj = {
name: 'zhangsan',
age: 12
}
// console.log(obj.name); // zhangsan
// 使用Object.defineProperty(obj, prop, descriptor)定义新属性或修改原有的属性。
Object.defineProperty(obj,'name',{
configurable:true, // 表示是否通过delete删除属性从而重新定义属性,能否修改属性的特性
// 或者能否把属性修改为访问器属性 默认true 可删除 false 不能删除
enumerable:true, // 表示能否通过for-in循环返回属性 默认true
writable:true, // 表示能否修改属性的值 默认true
value:'terry' // 属性的值 (要修改的)
})
console.log(obj.name); // terry
// Object.defineProperties(obj, props)定义多个新属性或修改原有的属性
// 注意两个方式的参数个数
var obj = new Object();
Object.defineProperties(obj, {
name: {
value: 'zhangsan',
configurable: false,
writable: true,
enumerable: true
},
age: {
value: 18,
configurable: true
}
})
console.log(obj.name, obj.age) // zhangsan, 18
// 读取属性的特征
var obj = {
name: '张三',
age: 18
}
// 方式一
var desc = Object.getOwnPropertyDescriptor(obj, 'name');
console.log(desc);
// 方式二
var desc = Object.getOwnPropertyDescriptors(obj);
console.log(desc)
访问器属性
这个属性不包含数据值,包含的是一对get和set方法,在读写访问器属性时,就是通过这两个方法来进行操作处理的。
// 访问器属性的四个特性:
// 1. configurable: false, 表示能否通过delete删除属性从而重新定义属性,能否修改属性的特性
// 或能否把属性修改为访问器属性, 默认为false
// 2. enumerable: false, 表示能否通过for-in循环返回属性,默认为false
// 3. get: function () {}; 在读取属性时调用的函数,默认值为undefined
// 4. set: function () {}; 在写入属性时调用的函数,默认值为undefined
// 访问器属性不能直接定义,要通过Object.defineProperty()这个方法来定义
var book = {
_year: 2020, //下划线表示是内部属性,只能通过对象的方法来读写
};
Object.defineProperty(book, 'year', {
get: function () {
// return 2021; // 若给定值 则输出2021 即使指定set方法也不能改变
return this._year; // 若set方法没有指定 返回2020
},
// 若只指定get方法,不指定set方法,那就默认该属性是只读的
set: function (newYear) {
if (newYear !== this._year) {
this._year = newYear
}
}
});
// 测试访问属性中的get,set方法
console.log('未修改的year:' + book.year);
book.year = 2022;
console.log('修改后的year:' + book.year);