object.create(proto, propertiesObject)
object.create()
是使用指定的原型proto
对象及其属性propertiesObject
去创建一个新的对象。(mdn)
-
proto
是必填参数,就是新创建出来的对象的原型 (新对象的__proto__
属性指向的对象),值得注意的是当proto
为null
的时候创建的新对象完全是一个空对象,没有原型(图一),也就是没有继承Object.prototype
上的方法。(如hasOwnProperty()
toString()
等) 图1 -
propertiesObject
是可选参数,作用就是给新对象添加新属性以及描述器(图2),具体可参考 Object.defineProperties() - mdn 的第二个参数。需要注意的是新添加的属性是新对象自身具有的属性也就是通过hasOwnProperty()
方法可以获取到的属性,而不是添加在原型对象里。(图3)
图3
具体三个步骤就是:
- 创建一个对象
- 继承指定父对象
- 为新对象扩展新属性
自己实现一个Object.create()
:
Object.myCreate = function (obj, properties) {
var F = function () {}
F.prototype = obj
if (properties) {
Object.defineProperties(F, properties)
}
return new F()
}
Object.myCreate({}, {a: {value: 1}}) // {a: 1}
new Object()
-
new
运算符是创建一个自定义对象或者具有构造函数的内置对象的实例mdn - 使用
new
运算符会创建一个新的对象,它继承自构造函数的prototype
,也就是说它的__proto__
属性会指向构造函数的prototype
-
new Object()
也就是具有构造函数的内置Object的实例,新创建的对象的__proto__
属性会指向Object的prototype
扩展:实例复现new的构造过程:
var objectFactory = function () {
var obj = new Object() // 从Object.prototype上克隆一个空对象 此时 __proto__ 指向Object.prototype
var Constructor = [].shift.call(arguments) //取得构造器
obj.__proto__ = Constructor.prototype // 指向构造器的prototype
var ret = Constructor.apply(obj, arguments)
return typeof ret === 'object' ? ret : obj
}
function Person (name) {
this.name = name
}
Person.prototype.getName = function () {
return this.name
}
var a = objectFactory(Person, 'nancy')
console.log(a.name) // nancy
console.log(a.getName) //nancy
console.log(Object.getPrototypeOf(a) === Person.protoType) //true
总结区别
-
Object.cerate()
必须接收一个对象参数,创建的新对象的原型指向接收的参数对象,new Object() 创建的新对象的原型指向的是 Object.prototype. (表述有点啰嗦,简洁点说就是前者继承指定对象, 后者继承内置对象Object) - 可以通过
Object.create(null)
创建一个干净的对象,也就是没有原型,而new Object()
创建的对象是 Object的实例,原型永远指向Object.prototype
.
网友评论