浅析字面量、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链中遍历该方法,当找到该方法后,又会生产方法调用必须的堆栈信息,方法调用结束后,还要释放该堆栈。
所以,相比来说,更推荐直接字面量创建,更简洁,更高效