浅析字面量、new操作符和Object.create(null)创建出来的对象的区别以及Object.create()方法理解

一、区别

1、字面量创建好处

  字面量创建对象更简单,方便阅读

  不需要作用域解析,速度更快

2、new 内部:4个步骤

  创建一个空对象;

  使新对象的__proto__指向原函数的prototype;

  改变this指向(指向新的obj)并执行该函数,执行结果保存起来作为result;

  判断执行函数的结果是否是Null/Undefined,如果是,则返回之前的新对象,否则返回result。

function myNew(fn, ...args) {
  // 创建一个空对象
  let obj = {};
  // 使空对象的隐式原型指向原函数的显式原型
  obj.__proto__ = fn.prototype;
  // this指向obj
  let result = fn.apply(obj, args);//相当于obj.fn(args)
  // 返回
  return result instanceof Object ? result : obj;
}

3、字面量和new创建出来的对象与Object.create(null)创建出来的对象的区别

  字面量和new创建出来的对象会继承Object的方法和属性,创建出来的对象的隐式原型(proto)会指向Object的显式原型;

  而Object.create(null)创建出来的对象原型为null,作为原型链的顶端,就没有继承Object的方法和属性。

 

二、Object.create() 介绍

  Object.create()方法创建一个新对象,使用现有的对象来提供新创建的对象的__proto__

1、参数:

  proto:新创建对象的原型对象(即新对象原型指向这个对象参数)

  propertiesObject(可选):新对象指定的属性,是一个对象形式的配置

    value: 属性的默认值, 默认为undefined

    congigurable: 能否使用delete、能否修改属性特性、或能否修改访问器属性、false为不可重新定义,默认值为true

    enumberable: 可枚举性,对象属性能否通过for-in 循环,默认为true

    writable: 对象属性是否可修改,默认为true,可修改,设置false可理解为常量不可修改

let newObj = Object.create(
 {name:'sun'},
 {
   age: {
     value: 24, // 属性默认值
     congigurable: false, // 设置false之后将不能不删除
     enumerable: true,
     writable: false,  // 设置false之后将不能修改
   }
 }
)

2、返回值:一个新对象,带着指定的原型对象和属性(它并不会继承源对象的属性)

3、创建空对象的区别

  如果你要创建一个干净的空对象,推荐使用Object.create(null),因为我们传入null当做它的参数,所以它创建的对象不会有原型,也不会有 Object 原型对象的任何属性(例如toString,hasOwnProperty等)

  Object.create(null) 可以创建一个干净且高度可定制的对象当做数据字典,进行循环取用,可以提高循环效率。这个时候如果对象有原型链,那便会在循环的时候去循环它的各个属性和方法,效率则会降低

4、创建对象的区别

(1)Object.create()创建的对象只是原型指向源对象,并不会继承它的任何属性;而new出来的对象是会继承原型对象的属性和方法。如下

let obj = {
  name: '阿彬',
  age: 10,
  foo: function() {
    console.log(this.age)
  }
}
let a = Object.create(obj)
let b = new Object(obj)
 
a.name = ''
b.name = ''
 
console.log(a.name,a,a.foo()); 
//彬 {name: '彬'} 10
        
console.log(b.name,b,b.foo());
//彬 {name: '彬', age: 10, foo: ƒ} 10

  可以看到,分别打印a和b,通过Object.create()创建的a是没有原型对象的age属性和foo方法的。而之所以它也可以执行foo方法,是因为向原型链追溯,找到了原型对象的这个方法执行了

5、字面量创建和new创建

  从创建对象的过程来讲,这两者底层实现基本是没有区别的。但是new Object()本质上是方法(只不过这个方法是内置的)调用, 既然是方法调用,就涉及到在proto链中遍历该方法,当找到该方法后,又会生产方法调用必须的堆栈信息,方法调用结束后,还要释放该堆栈。

  所以,相比来说,更推荐直接字面量创建,更简洁,更高效

posted @ 2017-11-02 20:12  古兰精  阅读(304)  评论(0编辑  收藏  举报