目录
Object.prototype.hasOwnProperty()
Object.prototype.propertyIsEnumerable()
对象
什么是对象?在我们的现实生活当中万物皆是对象,对象就是一个具体的事物,看得见摸得着的实物。例如,一本书、一辆汽车、一个人都是对象。而一个人的身高、体重、性别都是这个人对象的属性,人的走路和跑步、说话就是这个人对象的方法。
对象的创建
字面量模式
通过字面量模式的创建的对象的属性需要逗号 ',' 隔开(下文中的所有obj全部使用的是通过字面量模式创建的该变量)
var obj = {
name:'zhangsan',
age:20,
sayName:function(){
console.log(this.name);
}
}
构造函数模式
使用Object或者使用自定义构造函数来初始化对象(例如Student)
通过 .语法来向对象中添加我们需要的属性
var obj = new Object();
obj.name = 'zhangsan';
obj.age = 20;
obj.sayName = function(){
console.log(this.name);
}
//也可以这样创建对象
var obj = {};
obj.name = 'zhangsan';
obj.age = 20;
obj.sayName = function(){
console.log(this.name);
}
对象的访问
属性访问
通过 点语法 和 中括号 的方式来进行对象的属性访问
点后面直接跟的是对象的属性,如果属性存在可以访问到,如果属性不存在,得到undefined。 中括号的方法也同理。
console.log(obj.name); //'zhangsan'
console.log(obj['name']); //'zhangsan'
方法的访问
方法的访问主要是为了执行该对象中的方法,需要按照函数调用的方式去使用
//以下执行结果不一样
obj.sayName;//无执行结果
obj.sayName();//方法的使用
遍历对象中的属性
普通版的for循环可以遍历数组,但无法遍历对象
增强版的for循环:
for..in用于遍历数组或者对象的属性
obj对象:依次从obj中获取到属性名 “自定义变量名key”用来指定是数组的元素索引,也可以是对象的属性
for(var key in obj){
var value = obj[key];
console.log(value);
}
//zhangsan
//20
//[Function: sayName]
新增删除对象中的属性
只能删除对象中原有的自有属性
delete obj.age;
delete obj['name'];
delete obj.sayName //从obj对象中删除sayName属性
console.log(obj) //{}
新增对象的属性
obj.gender = 'female'
console.log(obj) //{ name:'zhangsan', age:20, [function:sayName], gender:'female'}
Object显示类型转换(强制类型转换)
Object类型转换到Boolean类型
除了空引用(null)会转换为false,其他都被转换为true
// 除了空引用(null)会转换为false,其他都被转换为true
// 使用Boolean包装器进行转换
console.log(Boolean(obj)); // true
Object类型转String类型
转换规则:
显示转换与隐式转换规则类似,当要将对象转换为String时:
1.先调用对象的toString方法
2.判断该方法的返回值是否为基础数据类型(Number,String,Boolean,Undefined,Null)
3.若返回值为基础数据类型,则转换规则按照相应数据类型的转换规则对其进行转换
4.若返回值不为基础数据类型,则在该返回值的基础上继续调用valueOf方法
5.判断valueOf的返回值是否为基础数据类型
6.判断是否为基础数据类型,若是基础数据类型则进行操作3
7.若仍旧不为基础数据类型则报错
console.log(obj.toString(), typeof obj.toString()); //[object Object] string
console.log(String(obj), typeof String(obj)); //[object Object] string
方法重写
1.如果只重写了valueOf()方法,则调用toString()方法。
2.如果只重写了toString()方法,则调用toString()方法。
3.如果两个方法都重写了,则调用valueOf(),并将返回值用String()转换。
var obj = {
name:'zhangsan',
age:20,
sayName:function(){
console.log(this.name);
},
/*
1.如果只重写了valueOf()方法,则调用toString()方法。
2.如果只重写了toString()方法,则调用toString()方法。
3.如果两个方法都重写了,则调用toString()。
4.如果上述中的toString()方法都无法转换成基础数据类型,那就调用valueOf()方法,若仍旧不为基础数据类型则报错
*/
toString:function(){
return "100";
},
valueOf:function(){
return 10;
}
};
console.log(Number(obj)); //100
Object类型转Number类型
转换规则:
显示转换与隐式转换规则类似,当要将对象转换为Number时:
1.先调用对象的valueOf方法
2.判断该方法的返回值是否为基础数据类型(Number,String,Boolean,Undefined,Null)
3.若返回值为基础数据类型,则转换规则按照相应数据类型的转换规则对其进行转换
4.若返回值不为基础数据类型,则在该返回值的基础上继续调用toString方法
5.判断toString的返回值是否为基础数据类型
6.判断是否为基础数据类型,若是基础数据类型则进行操作3
7.若仍旧不为基础数据类型则报错
console.log(Number(obj)); //NaN
方法重写
1.如果只重写了valueOf()或者toString()方法,则调用该方法,并将返回值用Number()转换。
2.如果两个方法都重写了,则调用valueOf(),并将返回值用Number()转换。
3.如果两个方法都没有重写,则返回NaN
var obj = {
name:'zhangsan',
age:20,
sayName:function(){
console.log(this.name);
},
/*
1.如果只重写了valueOf()或者toString()方法,则调用该方法,并将返回值用Number()转换。
2.如果两个方法都重写了,则调用valueOf(),并将返回值用Number()转换。
3.如果两个方法都没有重写,则返回NaN
*/
toString:function(){
return "100";
},
valueOf:function(){
return 10;
}
}
console.log(Number(obj)); //10
检测属性
检测一个属性是否属于某个对象。常用的方式主要有3种: in、Object.prototype.hasOwnProperty()、Object.prototype.propertyIsEnumerable()
in
检测某属性是否是某对象的自有属性或者是继承属性
console.log('name' in obj); //true
console.log('age' in obj); //true
console.log('gender' in obj); //false
//如果用in判断一个属性存在,这个属性不一定是obj的,它可能是obj继承得到的,如:
console.log('toString' in obj); // true
因为toString定义在object对象中,而所有对象最终都会在原型链上指向object,所以obj也拥有toString属性。
Object.prototype.hasOwnProperty()
检测给定的属性是否是对象的自有属性,对于继承属性将返回false
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
Object.prototype.propertyIsEnumerable()
propertyIsEnumerable()是hasOwnProperty()的增强版,除了是自身属性外,还要求是可枚举属性,即我们创建的属性。
console.log(obj.propertyIsEnumerable('name')); //true
console.log(obj.propertyIsEnumerable('age')); //true
console.log(obj.propertyIsEnumerable('toString')); //false,不可枚举
console.log(obj.propertyIsEnumerable('gender')); //false
深入理解对象-定义属性
ECMAScript中有两种属性:数据属性、访问器属性。
数据属性特性
configurable:true, //表示是否通过delete删除属性从而重新定义属性,能否修改属性的特性,默认为true
enumerable:true,//表示能否通过for-in循环返回属性 默认为true
writable:true, //表示能否修改属性的值 默认为true
value:'zhangsan' //属性的值
Object.defineProperty():
定义新属性或修改原有的属性。
//(属性所在的对象,属性的名字,一个描述符对象)
Object.defineProperty(obj,'name',{
configurable:true, //表示是否通过delete删除属性从而重新定义属性,能否修改属性的特性,默认为true
enumerable:true,//表示能否通过for-in循环返回属性 默认为true
writable:true, //表示能否修改属性的值 默认为true
value:'zhangsan'
})
console.log(obj.name);
Object.defineProperty(obj,"name",{enumerable:false})
console.log(obj.propertyIsEnumerable("name"));//false
Object.defineProperties():
定义一个或者多个新属性或修改原有的属性。
//defineProperties(目标对象,该对象的一个或者多个键值)
Object.defineProperties(obj, {
name: {
value: 'zhangsan',
configurable: false,// 不可以通过delete删除属性
writable: true,
enumerable: true
},
age: {
value: 18,
configurable: true
}
})
console.log(delete obj.name); //false
console.log(obj.name, obj.age) // zhangsan 18
读取属性的特性
Object.getOwnPropertyDescriptor():
返回指定对象上一个自有属性对应的属性描述符
var desc = Object.getOwnPropertyDescriptor(obj, 'name');
console.log(desc) 结果如下
// {
// configurable: true,
// enumerable: true,
// writable: true,
// value: "zhangsan"
// }
Object. getOwnPropertyDescriptors():
返回指定对象所有自有属性对应的属性描述符
var desc = Object.getOwnPropertyDescriptors(obj);
console.log(desc)
// {
// name: {
// value: 'zhangsan',
// writable: true,
// enumerable: true,
// configurable: true
// },
// age: { value: 20, writable: true, enumerable: true, configurable: true },
// sayName: {
// value: [Function: sayName],
// writable: true,
// enumerable: true,
// configurable: true
// }
// }
访问器属性特性
configurable:true, //表示是否通过delete删除属性从而重新定义属性,能否修改属性的特性,默认为false
enumerable:true,//表示能否通过for-in循环返回属性 默认为false
get:在读取属性时调用的函数,默认值为undefined
set:在写入属性时调用的函数,默认值为undefined
访问器属性不能直接定义,要通过Object.defineProperty()这个方法来定义。
/**
* 访问器属性:访问器属性不包含数值,它包含的是一对getter和setter函数;
* 访问器属性不能像数据属性一样直接定义,它必须使用Object.defineProperty()方法来定义
*/
var book = {
_year: 2020, //下划线表示是内部属性,只能通过对象的方法来读写
editor: 1
};
Object.defineProperty(book, 'year', {
get: function () {
return this._year;
},
// 若只指定get方法,不指定set方法,那就默认该属性是只读的
set: function (newYear) {
if (newYear !== this._year) {
this._year = newYear
this.editor ++
}
}
});
// 测试访问属性中的get,set方法
console.log('未修改的year:' + book.year);
book.year = 2021;
console.log('修改后的year:' + book.year);
console.log('修改year后的editor:' + book.editor);
// 访问器属性可以通过Object.getOwnPropertyDescriptor()查询
console.log(Object.getOwnPropertyDescriptor(book, '_year'));
序列化和反序列化
JSON.stringify(obj) 将对象序列化为JSON字符串,只能序列化对象可枚举的自有属性
JSON.parse(jsonStr) 反序列化
var json = JSON.stringify(obj);
console.log(json);//string类型的字符串
// 将JSON字符串转换为对象
var obj = JSON.parse(json);
console.log(obj);