JS手写ES6的Object.create方法

方法介绍

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

用法:

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

Object.defineProperties()方法直接在一个对象上定义新的属性或修改现有属性,并返回该对象。

Object.defineProperties()使用示例:

let obj1 = { a: 2, b: 3 }

Object.defineProperties(obj1, {
  a: {
    enumerable: false, // 数据、存储描述符号
    configurable: false, // 数据描述符
    writable: false, // 数据描述符
    value: 'xxx' // 数据描述符号
    get: function(){}, // 储存描述符
    set: function(){} // 储存描述符
  }
})

有关Object.defineProperties()的具体细节请看我的这篇文章:戳我传送

Object.create 返回值:一个新对象,带着指定的原型对象及其属性。

使用Object.create(null)的原因

很多框架源码作者使用它来初始化一个新的对象,难道是最佳实践?

通过Object.create(null)创建出来的对象,没有任何属性,显示No properties。我们可以将其当成一个干净的 map 来使用,自主定义 toString,hasOwnProperty等方法,并且不必担心将原型链上的同名方法被覆盖。

注意:{...}创建的对象,使用for in遍历对象的时候,会遍历原型链上的属性,带来性能上的损耗。使用Object.create(null)则不必再对其进行遍历了。

框架源码对性能的要求极高,哪怕是一点点,都值得关注。

开始手写

// 第一个参数传递null时,返回的实例原型为null
// 第一个参数类型只能是object、function或者null,否则报错。
// 第二个参数类型,不能是null,否则报错
// 第二个参数如果不为 undefined ,需要将其挂载到实例的  Object.defineProperties 上。

Object.mjy_create = function(proto, defineProperties) {
    if ( typeof proto !== 'object' && typeof proto !== 'function' ) {
      throw new TypeError(`Object prototype may only be an Object or null: ${proto}`)
    }
    if ( defineProperties === null ) {
      throw new TypeError('Cannot convert undefined or null to object')
    }
  
  	// 定义新对象 
      const obj = {}
    
      // 设置原型
      // obj.__proto__ = proto // 不建议这么做了
      // 通常,应该使用 Object.setPrototypeOf() 方法来设置对象的原型。
      // 因为 Object.prototype.__proto__ 访问器已被弃用。
       Object.setPrototypeOf(obj, proto) // 建议使用setPrototypeOf设置原型

    if ( defineProperties !== undefined ) {
      Object.defineProperties(obj, defineProperties)
    }
    return obj
  }
  let obj1={b:2}
  let obj2 = Object.mjy_create(obj1, { a: { enumerable: false } })
  console.log(obj2)//{}
  let obj2_ = Object.mjy_create(obj1, { a: { enumerable: true } })
  console.log(obj2_)//{ a: undefined }
  let obj3 = Object.create('222', undefined) // TypeError: Object prototype may only be an Object or null: 222
  let obj4 = Object.create(obj1, null) // TypeError: Cannot convert undefined or null to object
  console.log(obj2.a) // undefined
  
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

码上十七

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值