JS handwritten ES6 Object.create method

method introduction

The Object.create() method is used to create a new object, using an existing object as the prototype of the newly created object.

usage:

Object.create(proto,[propertiesObject])
  • proto: The prototype object of the newly created object.
  • propertiesObject (optional): If this parameter is specified and not undefined, the passed object's own enumerable properties ( that is, properties defined by itself, not enumerable properties on its prototype chain ) will be new The created object adds the specified property values ​​and corresponding property descriptors. These properties correspond to the second parameter of Object.defineProperties().

The Object.defineProperties() method defines new properties or modifies existing properties directly on an object and returns the object.

Example of using Object.defineProperties():

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

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

For details about Object.defineProperties(), please see my article: Poke me to send

Object.create Return value: a new object with the specified prototype object and its properties.

Reasons to use Object.create(null)

Many framework source code authors use it to initialize a new object, is it the best practice?

Objects created by Object.create(null) do not have any properties and show No properties. We can use it as a clean map, define toString, hasOwnProperty and other methods independently, and don't have to worry about overwriting the methods with the same name on the prototype chain.

Note: When using for in to traverse the object created by {...}, the properties on the prototype chain will be traversed, resulting in performance loss. Use Object.create(null) to no longer have to traverse it.

The framework source code has extremely high performance requirements, even if it is a little bit, it is worthy of attention.

start handwriting

// 第一个参数传递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
  

Guess you like

Origin blog.csdn.net/m0_65335111/article/details/127620727