先看原理
{}等同于new Object(),原型都是Object.prototypeObject.create()- 可以传 null
Object.create(null),当你传入 null 时 它没有原型 - 也可以传 对象
Object.create({...}),可指定原型。传入什么对象 就指定什么原型
- 可以传 null
new Object()
const obj1 = {
a: 10,
b: 20,
sum() {
return this.a + this.b
}
}
const obj3 = new Object(obj1)
obj1 === obj3 // true
new Object(obj_name)new Object()接受一个 别的对象的变量名/引用名,实际上的操作 就相当于 给接受到的这个对象 再取了一个别名,仅此而已
Object.create()
Object.create(null)
→ {} // 返回一个空对象
↓ No properties // 没有原型
Object.create({})
→ {}
↓ __proto__: Object // 有原型
new Object()
→ {}
↓ __proto__: Object
- 下面来看 一个很奇怪的现象
// 定义两个对象 const obj2 = { a: 10, b: 20, sum() { return this.a + this.b } } const obj5 = Object.create({ a: 10, b: 20, sum() { return this.a + this.b } }) // 下面我们来看看 有什么区别 obj2 → {a: 10, b: 20, sum: ƒ} obj5 → {} // obj5 是一个空对象 obj2.a → 10 obj5.a // 但是 obj5 又能正常访问 它里面的属性 → 10 obj5 ↓ {} ↓ __proto__: a: 10 b: 20 → sum: ƒ sum() → __proto__: Object-
为什么呢?
- 因为
obj5 = Object.create({...})他的原型是指向 它里面接收到的对象 - 虽然他自己是空对象,但是它会顺着原型往上找它自己原型,然后访问原型里面的方法
- 因为
-
- 下面再来看 一个有意思的东西
const obj1 = new Object({
a: 10,
b: 20,
sum() {
return this.a + this.b
}
})
const obj6 = Object.create(obj1)
// 下面看点有意思的
obj1
→ {a: 10, b: 20, sum: ƒ}
obj6
→ {}
obj1.c = 1000 // 给 obj1 添加属性 c
→ 1000
obj1
→ {a: 10, b: 20, c: 1000, sum: ƒ}
obj6.c // obj6 也会跟着 有了 属性c
→ 1000
obj6
↓ {}
↓ __proto__:
a: 10
b: 20
c: 1000
→ sum: ƒ sum()
→ __proto__: Object
obj6 === obj1 // false
obj6.__proto__ === obj1 // true
- obj6 的原型指向的对象的引用,跟 obj1 对象的引用 完全一样,就是同一个对象
- 所以 obj1 发生变化,obj6 也跟着发生变化