学习一下 Object.create()

141 阅读3分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第 19 天,点击查看活动详情

start

  • 最近有一个方法经常出现在我眼前:Object.create()
  • 今天就去学习一下这个方法;

MDN

Object.create() 方法用于创建一个新对象,使用现有的对象来作为新创建对象的原型(prototype)。

1. 语法

Object.create(proto)
Object.create(proto, propertiesObject)

2. 参数

  • proto

    新创建对象的原型对象。

  • propertiesObject 可选

    如果该参数被指定且不为 undefined,则该传入对象的自有可枚举属性(即其自身定义的属性,而不是其原型链上的枚举属性)将为新创建的对象添加指定的属性值和对应的属性描述符。这些属性对应于 Object.defineProperties() 的第二个参数。

3. 返回值

一个新对象,带着指定的原型对象及其属性。

基本使用与注意事项

  • 第一个参数必须传递。
Object.create()
// TypeError: Object prototype may only be an Object or null: undefined
  • 第二个属性尝试:
/* 传入数字不报错,但是不生效 */
var obj = Object.create({}, 1)
console.log(obj) // {}
/* 传入布尔值不报错,但是不生效 */
var obj = Object.create({}, false)
console.log(obj) // {}
/* 传入字符串报错 */
var obj = Object.create({}, 'str')
console.log(obj) // Uncaught TypeError: Property description must be an object: s // 属性描述必须是一个对象:s
/* 传入对象 */
var obj = Object.create({}, {})
console.log(obj) // {}

var obj = Object.create({}, { name: '123' })
console.log(obj) // TypeError: Property description must be an object: 123

var obj = Object.create({}, { name: { value: '123' } })
console.log(obj) // {name: '123'}

// 完整的用法
var obj = Object.create(
  {},
  {
    name: {
      value: '名称', // 包含这个属性的数据值
      configurable: true, // 表示能否通过 delete 删除属性,默认为 false;
      enumerable: true, // 是否可遍历,默认为 false;
      writable: true // 是否可修改,默认为 false;	
    },

    age: {
      value: '123', // 包含这个属性的数据值
      configurable: true, 
      enumerable: true, 
      writable: true 
    }
  }
)
console.log(obj) // { name: '名称', age: '123' }
  • 原型

正常的原型继承:

var person = {
  name: '人',
  age: 18,
  say() {
    console.log('你好')
  }
}

var obj = Object.create(person, {
  name: {
    value: '名称'
  },

  like: {
    value: 'study'
  }
})
console.log(obj) // {name: '名称', like: 'study'}

console.log(obj.name) // 名称
console.log(obj.age) // 18
obj.say() // 你好


console.log(obj.__proto__ === person) // true

null

var obj = Object.create(null)

console.log(obj.__proto__) // undefined

{}

var obj = Object.create({})

console.log(obj.__proto__) // {}

其他创建对象的方式

常见的创建对象的方式有两种:

  • 字面量
  • new的形式
var obj1 = { name: 11 }

var obj2 = new Object({ name: 22 })

var obj3 = Object.create({ name: 333 })

console.log(obj1, obj2, obj3)
/*

{name: 11}
{name: 22}
{}

*/
console.log(obj1.__proto__ === Object.prototype, obj2.__proto__ === Object.prototype, obj3.__proto__)

/*

true
true
{name: 333}

*/

个人小节:

  1. 字面量的形式创建的对象, 原型指向 Object.prototype;
  2. new的形式创建的对象,原型指向 new的那个构造函数;
  3. Object.create创建的对象,原型指向传入的第一个参数;

其他

看到有人说道 Object.create(null) 和 Object.create({})的区别,先去谷歌浏览器打印一下。

var obj = Object.create(null)

console.log(obj)

image-20220816233336141.png

var obj = Object.create({})

obj.__proto__.__proto__.__proto__===null

image-20220816233618213.png

结论:相对来说。以 null 为原型生成的对象,更纯粹,以至于没有从 Object.prototype 继承任何对象方法。而第一个参数为{}的情况,可以沿着原型链寻找直到寻找到 null , 所以它可以在原型链上获得Object.prototype 上的属性和方法。

end

  • 加油啦