1)Object.assign 合并对象
// 通过复制一个或多个对象来创建一个新的对象,就是合并多个对象为一个新的对象
var target = {
foo : 'hello',
// 相同的键,后者会覆盖前者
test : 'test',
}
// 合并的过程是复制对象源source 到一个新对象 - 这个过程可以实现克隆
Object.assign(target, {bar : 'bar'}, {baz : 'baz', test : 'text'});
console.log(target);
如果target为空,那就是在复制source的内容,只能实现浅复制,只拷贝外层对象。
2)Object.create 用来创建指定原型和属性控制的对象
//如何创建空对象?
var o = new Object();
// 至少继承了Object.prototype原型对象
console.log(o);
// 可以通过Object.create重写原型
var o = Object.create(null);
console.log(o);
完整用法有2个参数:Object.create(原型对象, 对象的属性描述)
var oo = Object.create(Object.prototype, {
// 以对象形式 来设置属性描述
// 每个属性也以对象形式来设置
foo : {
value : 'foo', // 设置值
enumerable : true, // 是否可枚举
writable : true, // 是否可写 - 修改
},
bar : {
value : 'bar',
enumerable : true,
writable : false,
},
test : {
get () {},
set () {}
}
})
console.log(oo);
create可以用来实现 构造函数的原型方法继承,通过修改原型链,即将子类的原型对象的原型对象 设为父类的原型对象:
Student.prototype = Object.create(Human.prototype)
3)Object.defineProperty 用来添加一个带描述的属性
var obj = { }
//这样添加属性除了值以外,没有任何其他描述信息
obj.name = 'zs'
// 如果要对属性进行封装 则需要添加属性描述
Object.defineProperty(o, "name", {
value : 'zs',
// 访问控制 - 封装权限
writable : false,
enumerable : false,
configurable : false, // 可配置,就是描述能不能被重置
});
还可以设置属性的拦截器,get/set方法对 每次在读写时调用(调用就是在拦截处理 - 鉴权)
Object.defineProperty(o, "gender", {
// 读取属性时 调用
get () {
// return 'gender的值是:' + this._gender;
console.error(new Error('gender is not defined'));
return '';
},
// 写入属性是 调用
set (val) {
// console.log(val);
this._gender = val;
}
});
复数方法:defineProperties 同时添加多个属性描述
Object.defineProperties({
_gender : 'nan'
}, {
name : {
value : 'ls',
enumerable : true,
writable : false
},
gender : {
get () {
return this._gender;
},
set (val) {
this._gender = val;
}
},
//...
})
vue数据代理如何实现?
// 1、要借助于内置方法 defineProperty或者defineProperties
// 2、给属性添加get/set拦截器,内部操作data数据
var o = {
// 数据存在o.data里面
data : {
a : 1,
b : 2
},
}
// 正常情况下 访问data数据,需要使用o.data来操作
// 这样比较麻烦,我们希望让o代理data里面数据,直接用o来访问
// 可以使用defineProperty来实现数据的代理,把o.data里面的数据写入o
Object.keys(o.data).forEach(function (item, index) {
// ['a', 'b'].forEach(item)
// o[item] = o.data[item]; // 这样是可以读取,也可以修改 但是和data没有半毛钱关系
// item为每个属性 添加给o
Object.defineProperty(o, item, {
get () {
// 拦截后 要读取data里面的值
return o.data[item]
},
set (val) {
// 拦截后 要在内部修改data里面的值
o.data[item] = val;
}
})
})
4)Object.keys、Object.values、Object.entries 从对象中提取键和值
var flowers = {
'name1' : '大佐',
'name2' : '萍姐',
'name3' : '英勇',
'name4' : '清华',
'name5' : '陆军'
}
// 获取对象所有键,返回可枚举的属性 - enumberable
var arr = Object.keys(flowers);
console.log(arr);
// 获取对象的所有值,返回的数组 - 对象转数组的一种形式
var arr = Object.values(flowers);
console.log(arr);
// entries()方法 也能实现对象转化数组:
var arr = Object.entries(flowers);
// 返回键值对集合的二维数组,这种结构 可以很方便的用来实现和Map数据的转化
console.log(arr);
面向对象的封装性:(模拟其他面向对象来实现 稍显复杂)
// 属性封装,通过Object.create()方法或者Object.defineProperty() 指定属性的封装
// 对象封装,Object.preventDefault(),Object.freeze(),Object.seal() 个体的封装
// 类的封装,在类中 使用#设置私有属性,所有的实例对象都要遵循