目录
定义单个属性 静态方法 Object.defineProperty
定义多个属性 静态方法 Object.defineProperties
一次读取一个 getOwnPropertyDescriptor(obj,属性)
一次读取多个 getOwnPropertyDescriptors(obj)
JS原型
JavaScript是基于原型的我们创建的每个函数都有一个 prototype(原型)属性,这个属性是一个指针,指向一个对象,而这个对象的用途是包含可以由特定类型的所有实例共享的属性和方法。
简单来说,就是当我们创建一个函数的时候,系统就会自动分配一个 prototype
属性,可以用来存储可以让所有实例共享的属性和方法。
关系如下图:
图解:
每一个原型对象都有一个指针指向构造函数
/**
* 每一个构造函数都有一个原型对象
*/
console.log(Object.prototype);
console.log(Object.prototype.constructor);
每一个原型对象都有一个指针指向构造函数
/**
* 每一个原型对象都有一个指针指向构造函数
*/
console.log(Object.prototype.constructor===Object);
构造函数创建的实例对象都有一个指针指向原型对象
// 构造函数创建的实例对象都有一个指针指向原型对象
var obj = new Object();
console.log(obj.__proto__===Object.prototype);
其中,实例可以访问原型属性和方法。
// 实例可以访问原型属性和方法
console.log(obj.__proto__.constructor);
console.log(obj.__proto__.toString());
console.log(obj.__proto__.valueOf());
console.log(obj.valueOf()); //{}
console.log(Object.prototype.valueOf()); //{}
console.log(obj.constructor===Object.prototype.constructor);
console.log(obj.toString()===Object.prototype.toString());
console.log(obj.valueOf()===Object.prototype.valueOf()); //false
// console.log(obj.valueOf()===obj.__proto__.valueOf())
console.log(obj.__proto__.valueOf()===Object.prototype.valueOf());
console.log(obj.toLocaleString());
var now = new Date();
console.log(now.toString());
console.log(now.toLocaleString());
数据属性定义方法
定义单个属性 静态方法 Object.defineProperty
格式:目标对象 ,定义属性,属性描述符 {}
var obj = {
name:'zhangsan',
age:20,
gender:'male'
}
Object.defineProperty(obj,'name',{
value:'kyo',
// 是否可删除 默认为true
configurable:false,
// 是否可写
writable:false,
// 是否可枚举
enumerable:false
})
delete obj.name;
obj.name = 'lisi';
console.log(obj);
console.log(obj.name);
for(let key in obj){
console.log(key);
}
即使设置了不可枚举,还可以用console.log(obj.name)访问到该属性。
定义多个属性 静态方法 Object.defineProperties
格式:目标对象,{定义属性{属性描述符}}
var obj = {
age:18,
gender:'male',
no:'web2301',
};
// 定义多个属性
Object.defineProperties(obj,{
gender:{
// 数据属性 可读 可写 可删 可遍历
configurable:false
},
age:{
writable:false
},
no:{
enumerable:false
},
});
delete obj.gender;
obj.age = 20;
console.log(obj.propertyIsEnumerable('no'));
console.log(obj);
读取属性的特性
一次读取一个 getOwnPropertyDescriptor(obj,属性)
var obj = {
name:'zhangsan',
age:12
};
/**
* 读取属性的特性 getOwnPropertyDescriptor(obj,属性)
* 一次读取一个属性
*/
Object.defineProperty(obj,'name',{
configurable:false,
writable:false,
})
console.log(Object.getOwnPropertyDescriptor(obj,'name'));
console.log(Object.getOwnPropertyDescriptor(obj,'age'));
console.log(Object.getOwnPropertyDescriptor(obj,'gender'));
一次读取多个 getOwnPropertyDescriptors(obj)
/**
* 一次读取多个属性的特性
*/
console.log(Object.getOwnPropertyDescriptors(obj),'读取多个属性特性');
访问器属性的定义 defineProperty
访问器的属性不可以直接定义 必须使用 defineProperty方法 set和get函数 配置属性是否可读或者可更改。
var book = {
// 如果是下划线开头的属性 一般表示对象的私有属性 一般不直接访问
_year:2023
}
// 访问器的属性不可以直接定义 必须使用 defineProperty方法 set和get函数 配置属性是否可读或者可更改
Object.defineProperty(book,'year',{
// configurable:false,
// enumerable:false,
// 读取该属性的时候会触发
get:function(){
console.log('我被读取了');
// return false;
return this._year;
},
set:function(newYear){
// 监听到值的变化
if(this._year!=newYear){
this._year = newYear;
}
}
});
book.year = 2026; //触发set函数
console.log(book.year,book._year);
对象的序列化
对象序列化是指将对象的状态转换为字符串,也可以反序列化,将字符串还原为对象函数。
RegExp,Error对象,undefined值不能序列化和反序列化。
JSON.stringify(obj) 将对象序列化为JSON字符串,只能序列化对象可枚举的自有属性
JSON.parse(jsonStr) 反序列化。
var obj = {
name:'zhangsan',
age:12
};
/**
* 后端 需要json字符串格式的对象
* JSOn.stringify 将js对象转换为json字符串对象
* 将对象进行序列化
*/
var jsonStr = JSON.stringify(obj);
console.log(jsonStr,typeof(jsonStr));
/**
* 将json字符串进行反序列化 将json字符串转换为js对象
* JSON.parse()
* 实现深拷贝的方式 1.利用序列化和反序列化实现深拷贝
* 2.使用...拓展运算符 {...obj}
*/
var jsObj = JSON.parse(jsonStr);
console.log(jsObj,typeof(jsObj));
console.log(obj === jsObj);