JavaScript对象
对象是一个包含相关数据和方法的集合(通常由一些变量和函数组成,我们称之为对象里面的属性和方法)
1.对象的创建
字面量模式
var obj = {
name:'TTTony',
age:21,
sayName:function(){
console.log(this.name);
}
}
构造函数模式
var obj = new Object();
obj.name = 'TTTony';
obj.age = 21;
obj.sayName = function(){
console.log(this.name);
}
2.对象的访问
- 属性的访问
点访问法、中括号访问法
obj.name // TTTony
obj['name'] //TTTony
- 方法的访问
方法的访问主要是为了执行该对象中的方法,需要按照函数调用的方式去使用
//以下代码执行结果不一样
obj.sayName;
obj.sayName(); // 方法的使用
- 遍历对象中的属性
for…in用于遍历数组或者对象的属性
for(var key in obj){
var value = obj[key];
}
自定义变量名key,可以是数组的元素索引,或对象的属性。
3.新增、删除对象中的属性
delete obj.pro; // 删除对象中的属性
obj.newproname = 'value'; // 新增对象中的属性
4.Object显示类型转换(强制类型转换)
- Boolean(value) :把给定的值转换成Boolean型
- String(value):把给定的值转换成字符串
- Number(value):把给定的值转换成数字(可以是整数或浮点数)
- Object类型到Boolean类型
var obj = {
name:'TTTony',
age:21
};
//使用Boolean()包装器进行转换
console.log(Boolean(obj));
- Object类型转换String类型
var obj = {
name:'TTTony',
age:21,
// 对toString方法进行重写,进行我们想要的转换
toString:function(){
return this.name +"-"+ this.age;
}
};
console.log(obj.toString(), typeof obj.toString());
console.log(String(obj), typeof String(obj));
转换规则:
1) 先调用对象的toString方法
2) 判断该方法的返回值是否为基础数据类型(5种基本数据类型)
3) 若返回值为基础数据类型,则转换规则按照相应数据类型的转换规则对其进行转换
4) 若返回值不为基础数据类型,则在该返回值的基础上继续调用valueOf方法
5) 判断valueOf的返回值是否为基础数据类型
6) 判断是否为基础数据类型,若是基础数据类型则进行操作3
7) 若仍旧不为基础数据类型则报错
- Object类型转换Number类型
var obj = {
name:'TTTony',
age:21,
// 1.如果只重写了valueOf()或者toString()方法,则调用该方法,并将返回值用Number()转换。
// 2.如果两个方法都重写了,则调用valueOf(),并将返回值用Number()转换。
// 3.如果两个方法都没有重写,则返回NaN
toString:function(){
return "100";
},
valueOf:function(){
return 10;
}
};
console.log(Number(obj));
转换规则:
1) 先调用对象的valueOf方法
2) 判断该方法的返回值是否为基础数据类型(Number,String,Boolean,Undefined,Null)
3) 若返回值为基础数据类型,则转换规则按照相应数据类型的转换规则对其进行转换
4) 若返回值不为基础数据类型,则在该返回值的基础上继续调用toString方法
5) 判断toString的返回值是否为基础数据类型
6) 判断是否为基础数据类型,若是基础数据类型则进行操作3
7) 若仍旧不为基础数据类型则报错
5.属性检测
检测一个属性是否属于某个对象:
in
检测属性是否是某对象的自有属性或继承属性
console.log("age" in obj); //若存在 返回true
Object.prototype.hasOwnProperty()
检测是否是自有属性 ,继承属性返回false
var obj = {
name:'TTTony',
age:21,
school:'家里蹲大学'
}
console.log(obj.hasOwnProperty('name')); //true
console.log(obj.hasOwnProperty('toString')); //false,toString为继承属性
console.log(obj.hasOwnProperty('gender')); //false,对象中没有gender属性
Object.prototype.propertyIsEnumerable()
检测属性是否是自有属性,且是我们创造的属性(可枚举)
var obj = {
name:'TTTony',
age:21,
school:'家里蹲大学'
}
console.log(obj.propertyIsEnumerable('name')); //true
console.log(obj.propertyIsEnumerable('toString')); //false,toString不可枚举
console.log(obj.propertyIsEnumerable('gender')); //false,对象中没有gender属性
6.Object原型属性及方法
在Object的构造函数的原型对象中的属性和方法都可以被Object构造函数的实例所继承
每个构造函数都有一个原型对象,原型对象都包含一个指向构造函数的指针,实例都包含一个指向原型对象的内部指针。 ----《JavaScript高级程序设计》
Object原型中常用的方法
1)constructor 保存用户创建当前对象的函数
2)hasOwnProperty(proName) 检查属性名是否是对象的自有属性
3) propertyIsEnumerable(proName) 检查给定的属性在当前对象实例中是否存在
4)valueOf() 返回字符串、数值、布尔
5)toString() 返回对象的字符串表示
6)isPropertyOf() a.isPropertyOf(b) 若a是b的原型,返回true ;若b不是对象 或 a不是b的原型,返回false
7.深入理解对象-定义属性
ECMAScript中有两种属性:数据属性、访问器属性。
这两种属性用于设置属性的高级属性,例如该属性是否可以配置,是否可以读写,是否可以遍历,并且可以通过setter,getter来监听数据的改变。
数据属性特性
- [[Configurable]] :表示是否通过delete删除属性从而重新定义属性,能否修改属性的特性,或者能否把属性修改为访问器属性。 当为false时,不能重新定义不能使用delete删除
- [[Enumerable]] :表示能否通过for-in循环返回属性
- [[Writable]] :表示能否修改属性的值
- [[Value]] :包含这个属性的数据值
修改默认的属性特性:
Object.defineProperty(属性所在的对象obj, 属性的名字prop, 一个描述符对象descriptor)
Object.defineProperty(obj, 'name', {
configurable:true,
enumerable:true,
writable:true,
value:'TTTony'
})
console.log(obj.name);
Object.defineProperty(obj,'name',{enumerable:false}); //修改默认属性的特性
obj.propertyIsEnumerable("name"); //false
修改多个默认属性的特性:
Object.defineProperty(obj, props)
var obj = new Object();
Object.defineProperties(obj, {
name: {
value: 'TTTony',
configurable: false,
writable: true,
enumerable: true
},
age: {
value: 21,
configurable: true
}
})
console.log(obj.name, obj.age) // zhangsan, 18
读取属性的特性
Object.getOwnPropertyDescriptor(obj, prop)
返回指定对象上的一个自有属性的属性描述符
var person = {
name: 'TTTony',
age: 21
}
var desc = Object.getOwnPropertyDescriptor(person, 'name');
console.log(desc);
// {
// configurable: true,
// enumerable: true,
// writable: true,
// value: "TTTony"
// }
Object.getOwnPropertyDescriptors(obj)
返回指定对象的所有自身属性的属性描述符,若没有自身属性 返回空对象
var obj = {
name:'tony',
age:21
};
var desc = Object.getOwnPropertyDescriptors(obj);
console.log(desc);
//{
// name: {
// value: 'tony',
// writable: true,
// enumerable: true,
// configurable: true
// },
// age: { value: 21, writable: true, enumerable: true, configurable: true }
//}
访问器属性
这个属性不包含数据值,包含的是一对get和set方法,在读写访问器属性时,就是通过这两个方法来进行操作处理的
- [[Configurable]] :表示是否通过delete删除属性从而重新定义属性,能否修改属性的特性,默认为false
- [[Enumerable]] :表示能否通过for-in循环返回属性,默认为false
- [[Get]] :在读取属性时调用的函数,默认值为undefined
- [[Set]] :在写入属性时调用的函数,默认值为undefined
/**
* 访问器属性:访问器属性不包含数值,它包含的是一对getter和setter函数;
* 访问器属性不能像数据属性一样直接定义,它必须使用Object.defineProperty()方法来定义
*/
var obj = {
_name:'tony', //下划线表示是内部属性,只能通过对象的方法来读写
age:21
};
Object.defineProperty(obj, 'name', {
get:function(){
return this._name;
},
// 若只指定get方法,不指定set方法,那就默认该属性是只读的
set:function(newName){
if(newName !== this._name){
this._name = newName;
this.age++;
}
}
});
// 测试访问器中的get和set方法
console.log("未修改的name:" + obj.name);
obj.name = 'zhu';
console.log('修改之后的name:' + obj.name);
console.log('修改name之后的age:' + obj.age);
// 问器属性可以通过Object.getOwnPropertyDescriptor()查询
console.log(Object.getOwnPropertyDescriptor(obj,'_name'));
8.对象序列化
对象序列化是指,将对象的状态转换为字符串。
也可以反序列化,将字符串还原为对象函数。
JSON.stringify(obj) 将对象序列化为JSON字符串,只能序列化对象可枚举的自有属性
JSON.parse(jsonStr) 反序列化
var obj = {
name:'tony',
age:21
}
console.log(obj); // 打印出对象 { name:'tony', age:21 }
// 将对象转换成字符串
var json = JSON.stringify(obj);
console.log(json); // 打印出字符串 { name:"tony", age:21 }
console.log(JSON.parse(json)); //将字符串转换成对象后打印