Object.create
基本用法
Object.create()方法是ECMAScript5中新增的,用来规范化原型式继承的。
object.create(proto, propertiesObject)
object.create() 是使用指定的原型proto对象及其属性propertiesObject去创建一个新的对象。
这个方法接收两个参数,一个是用作新对象原型的对象,另一个是新对象定义额外属性的(可选)对象。
-
proto 是必填参数,就是新创建出来的对象的原型 (新对象的 __proto__属性指向的对象),值得注意的是当proto为null的时候创建的新对象完全是一个空对象,没有原型,也就是没有继承Object.prototype上的方法。(如hasOwnProperty() toString() 等)
-
propertiesObject是可选参数,作用就是给新对象添加新属性以及描述器(图1),需要注意的是新添加的属性是新对象自身具有的属性也就是通过hasOwnProperty() 方法可以获取到的属性,而不是添加在原型对象里。
var person = { name: "Nicholas", friends: ["John", "Jane"] // 引用类型值属性共享 } var onePerson = Object.create(person); // onePerson继承person对象 onePerson.name = "Greg"; onePerson.friends.push("Mike"); console.log(onePerson.name); // Greg console.log(onePerson.friends); // ["John", "Jane", "Mike"] var anotherPerson = Object.create(person); console.log(anotherPerson.name); // Nicholas anotherPerson.friends.push("Jacky"); console.log(anotherPerson.friends); // ["John", "Jane", "Mike", "Jacky"] // 第二个参数对象格式与Object.defineProperties()方法的第二个参数格式相同 var theOtherPerson = Object.create(person, { name: { configurable: false, // 不可修改 value: "Greg" } }); console.log(theOtherPerson.name); // Greg theOtherPerson.name = "Bob"; // 失效 console.log(theOtherPerson.name); // Greg
手写Object.create
具体三个步骤就是:
-
创建一个对象
-
继承指定父对象
-
为新对象扩展新属性
Object.myCreate = function (proto, properties) { var F = function () { }; F.prototype = proto; if (properties) { Object.defineProperties(F, properties); } return new F(); } Object.myCreate({}, { a: { value: 1 } }); // {a: 1}
new Object
new 运算符是创建一个自定义对象或者具有构造函数的内置对象的实例。
使用new运算符会创建一个新的对象,它继承自构造函数的prototype,也就是说它的__proto__属性会指向构造函数的prototype,new Object() 也就是具有构造函数的内置Object的实例,新创建的对象的__proto__属性会指向Object的prototype。
手写new
function newObj() {
var con = [].shift.call(arguments, 1);
var obj = Object.create(con.prototype);
var result = con.apply(obj, arguments);
return result instanceof Object && result ? result : obj;
}
总结
Object.cerate() 必须接收一个对象参数,创建的新对象的原型指向接收的参数对象,new Object() 创建的新对象的原型指向的是Object.prototype。(表述有点啰嗦,简洁点说就是前者继承指定对象, 后者继承内置对象Object)
可以通过Object.create(null) 创建一个干净的对象,也就是没有原型,而 new Object() 创建的对象是 Object的实例,原型永远指向Object.prototype。
参考
object.create与new object的区别,手写一个object.create