let obj = {}
// 等同于
let obj = new Object()
求证
let obj = {
url: 'web03.cn'
}
obj.__proto__.name = '零三'
console.log(obj)
console.log({})
let obj1 = new Object()
console.log(obj1)
以上已经求证了{}等同于new Object() 以下反过来求证new Object()等同于{}
Object.prototype.name = '零三'
let obj = {
url: 'web03.cn'
}
console.log(obj)
console.log({})
let obj1 = new Object()
console.log(obj1)
结果都为
let obj1 = {
a:1,
b:2
}
let obj2 = {
a: 2,
x:3,
y:4
}
let obj3 = {
m:5,
n:6
}
let obj4 = Object.assign(obj1,obj2,obj3)
console.log('obj1=',obj1)
console.log('obj2=',obj2)
console.log('obj3=',obj3)
console.log('obj4=',obj4)
new Object() 通过构造函数来创建对象, 添加的属性是在自身实例下。
Object.create() es6创建对象的另一种方式,可以理解为继承一个对象, 添加的属性是在原型下。
Object.prototype.name = '零三'
let obj = Object.create(null)
let obj1 = Object.create({url: 'web03.cn'})
console.log(obj)
console.log(obj1)
console.log(obj1.url)
Object.create() 方法创建的对象时,属性是在原型下面的
此时这个值不是obj自身的,是它通过原型链proto来访问到url的值。
创建对象属性的性质不同
// 创建一个以另一个空对象为原型,且拥有一个属性p的对象
let obj = Object.create({}, {url:{value: 'web03.cn'}})
// 省略了的属性特性默认为false,所以属性url是不可写,不可枚举,不可配置的
obj.url = 'https://web03.cn'
console.log(obj.url)//web03.cn
obj.name = '零三'
console.log(obj.name)//零三
for (let key in obj) {
console.log(obj[key])//url不可枚举不能输出,结果只输出name的值
}
let isDel = delete obj.url
console.log(isDel)//false
console.log(obj)
Object.create() 用第二个参数来创建非空对象的属性描述符默认是为false的,而构造函数或字面量方法创建的对象属性的描述符默认为true
类似于
//创建一个构造函数或者类
let People = function(){}
People.prototype.url = 'web03.cn'
People.prototype.printUrl = function() {}
//通过构造函数创建实例
let p = new People();
console.log(p.__proto__ === People.prototype) // true
NO.4 Object.getPrototypeOf()
Object.getPrototypeOf用于读取一个对象的原型对象
Object.getPrototypeOf('foo') === String.prototype // true
Object.getPrototypeOf(true) === Boolean.prototype // true
NO.5 Object.assign()
Object.assign会改变原有的目标对象
let obj1 = {
a:1,
b:2
}
let obj2 = {
a: 2,
x:3,
y:4
}
let obj3 = {
m:5,
n:6
}
let obj4 = Object.assign(obj1,obj2,obj3)
console.log('obj1=',obj1)
console.log('obj2=',obj2)
console.log('obj3=',obj3)
console.log('obj4=',obj4)
Object.assign不能合并不能被枚举的对象
let obj = {
name: '零三',
url: 'web03.cn'
};
Object.defineProperty(obj,'name', {
enumerable: false, // 设为可枚举,不然 Object.assign 方法会过滤该属性
get(){
console.log('不会输出')
return this.name
}
});
let obj1 = Object.assign(Object.create(Object.getPrototypeOf(obj)), obj)
console.log(obj1)
Object.assign() 方法不能正确拷贝 get ,set 属性
let obj = {
name: '零三',
url: 'web03.cn'
};
function setName() {
this.name = '零零三';
}
Object.assign(setName.prototype, obj)
let result = new setName()
console.log(result)
Object.defineProperty(result,'getName', {
enumerable: true,
get(){
return "我是:" + this.name
}
});
let result2 = Object.assign(Object.create(Object.getPrototypeOf(obj)), obj)
console.log(result2)
原型属性的继承 拷贝一个构造函数的实例
// 继承
let obj = {
name: '零三'
};
function setName() {
this.name = '零零三';
}
// console.log(setName.prototype = obj)
// console.log(setName.prototype.constructor === setName)//false
Object.assign(setName.prototype, obj)
console.log(setName.prototype.constructor === setName)
let result = new setName();
console.log(result)
console.log(result.name)
console.log(result.__proto__.name)
不能拷贝到继承或原型上的方法的
let obj = {
name: '零三',
url: 'web03.cn'
};
function setName() {
this.name = '零零三';
}
Object.assign(setName.prototype, obj)
let result = new setName();
console.log(result)
let result2 = Object.assign({},result)
console.log(result2)
因为 Object.assing 是不能拷贝到继承或原型上的方法的。所以 实例result2 没有 result原型上的内容
实现原型属性的拷贝let obj = {
name: '零三',
url: 'web03.cn'
};
function setName() {
this.name = '零零三';
}
Object.assign(setName.prototype, obj)
let result = new setName();
console.log(result)
let result2 = Object.create(Object.getPrototypeOf(result), Object.getOwnPropertyDescriptors(result));
console.log(result2);
可以把Object.create()的参数理解为:第一个参数是放在新对象的原型上的,第二个参数是放在新对象的实例上的。
所以 Object.getPrototypeOf() 得到的是 result 对象的原型,然后作为第一个参数,所以会在新对象result2 的原型上。
Object.getOwnPropertyDescriptors() 得到是 result 对象自身的可枚举属性,作为第二个参数,放在 result2 的实例上。因为Object.assign() 方法不能正确拷贝 get ,set 属性(上面有提到)
实现get 、set 属性的正确拷贝let obj = {
name: '零三',
url: 'web03.cn'
}
let obj2 = {
__proto__: obj,
age: 18,
getAge() {
return this.age
},
get getAge2() {
return this.age
}
};
Object.defineProperty(obj2,'getName', {
enumerable: true,
get(){
return "我是:" + this.name
}
});
let result = Object.create(obj, Object.getOwnPropertyDescriptors(obj2))
console.log(result)