作用
- 创建一个新对象,该对象继承自指定的原型对象,可实现基于原型的继承
原理
- 基于原型链机制,调用ceate()时,会创建一个新对象,该对象内部的prototype属性会被设置为传入的proto对象,
- 这意味着新对象会自动继承proto传入对象的所有属性和方法
优点
精准控制原型
便捷简单
纯原型继承:不依赖类和构造函数的概念
缺点
IE8以下不兼容
运用场景
const a = Object.create(null) // 创建一个没有原型的干净对象
a.toString // undefined
const b = Object.create({}) // 普通使用场景
b.toString // function
使用语法
-
Object.create(proto, [propertiesObject])
proto:必需参数,指定新对象的原型对象。propertiesObject:可选参数,用于为新对象定义额外的属性。数据描述属性value: 属性值,默认为undefinedwritable: 是否可被赋值,默认是false
存取描述属性get: 函数,访问该属性时回调这个函数并返回返回值,默认是undefinedset:函数,给该属性赋值时会回调这个函数并传入新值,默认undefined
通用描述属性configurable: 布尔值,是否可以被删除,默认falseenumerable: 布尔值,是否可被枚举,默认false
- 需要注意:
数据描述属性 和存取描述属性不可同时定义,否则报错
var a = Object.create({}, { name: { value: 'name1', get () { console.log('test value') } } }) // 报错
使用示范
// 数据描述属性 const a = Object.create({}, { name: { value: 'name1', writable: true } }) console.log(a) // {name: 'name1'} a.name = 1 console.log(a.name) // name1 赋值修改被禁止 // 存取描述属性 const a = Object.create({}, { name: { get() { return `${this.nameA} ${this.nameB}` }, set(value) { this.nameA = value this.nameB = value }, enumerable: true, configurable: true } }) console.log(a.name) // 'undefined undefined' a.nameA = 'nameA' a.nameB = 'nameB' console.log(a.name) // 'nameA nameB' a.name = 'nameC' console.log(a.nanme) // 'nameC nameC'
直接赋值对象 和 Object.create创建对象的区别
- 直接赋值
- 直接赋值b1和a1之间的关系是引用赋值,在内存中是同一个内容,修改其中一方会影响另外一方
var a1 = {a:1}
var b1 = a1
- create创建
- Object.create 会在内存中创建一个新的对象b2,其原型为a2,继承a2的所有属性和方法,它们是不同对象 修改b2自身属性不影响a2的属性
// Object.create
var a2 = {a:1}
var b2 = Object.create(a2)
console.log(b2) // {} 在内存中创建一个新对象,其__proto__指向了a2
console.log(b2.a) // 1 ,首先在b2上找不到a属性,然后沿着原型找到a2上面的a并返回出来
b2.a = 2
console.log(b2) // {a: 2},在自身创建了a属性
console.log(a2.a) // 1 ,由于b2自身已经有了a属性,所以获取和设置a属性的时候都是获取设置b2自身的,a2上面的不受影响
b2.__proto__.a = 3
console.log(b2) // {a: 2}
console.log(a2.a) // 3 ,被b2找到原型修改到了a2上的a属性