Object.create()
方法會使用指定的原型對象及其屬性去建立一個新的對象。segmentfault
Object.create(proto[, propertiesObject])
undefined
,則是要添加到新建立對象的可枚舉屬性(即其自身定義的屬性,而不是其原型鏈上的枚舉屬性)對象的屬性描述符以及相應的屬性名稱。這些屬性對應Object.defineProperties()
的第二個參數。在指定原型對象上添加新屬性後的對象。瀏覽器
若是propertiesObject
參數不是 null
或一個對象,則拋出一個 TypeError
異常。函數
Object.create
實現類式繼承下面的例子演示瞭如何使用Object.create()
來實現類式繼承。這是一個全部版本JavaScript都支持的單繼承。this
// Shape - superclass function Shape() { this.x = 0; this.y = 0; } // superclass method Shape.prototype.move = function(x, y) { this.x += x; this.y += y; console.info('Shape moved.'); }; // Rectangle - subclass function Rectangle() { Shape.call(this); // call super constructor. } // subclass extends superclass Rectangle.prototype = Object.create(Shape.prototype); Rectangle.prototype.constructor = Rectangle; var rect = new Rectangle(); console.log('Is rect an instance of Rectangle?', rect instanceof Rectangle); // true console.log('Is rect an instance of Shape?', rect instanceof Shape); // true rect.move(1, 1); // Outputs, 'Shape moved.'
若是你但願能繼承到多個對象,則能夠使用混入的方式。prototype
function MyClass() { SuperClass.call(this); OtherSuperClass.call(this); } // inherit one class MyClass.prototype = Object.create(SuperClass.prototype); // mixin another Object.assign(MyClass.prototype, OtherSuperClass.prototype); // re-assign constructor MyClass.prototype.constructor = MyClass; MyClass.prototype.myMethod = function() { // do a thing };
Object.assign 會把 OtherSuperClass
原型上的函數拷貝到 MyClass
原型上,使 MyClass 的全部實例均可用 OtherSuperClass 的方法。Object.assign 是在 ES2015 引入的,且可用 polyfilled。要支持舊瀏覽器的話,可用使用 jQuery.extend() 或者 _.assign()。code
Object.create
的 propertyObject
參數var o; // 建立一個原型爲null的空對象 o = Object.create(null); o = {}; // 以字面量方式建立的空對象就至關於: o = Object.create(Object.prototype); o = Object.create(Object.prototype, { // foo會成爲所建立對象的數據屬性 foo: { writable:true, configurable:true, value: "hello" }, // bar會成爲所建立對象的訪問器屬性 bar: { configurable: false, get: function() { return 10 }, set: function(value) { console.log("Setting `o.bar` to", value); } } }); function Constructor(){} o = new Constructor(); // 上面的一句就至關於: o = Object.create(Constructor.prototype); // 固然,若是在Constructor函數中有一些初始化代碼,Object.create不能執行那些代碼 // 建立一個以另外一個空對象爲原型,且擁有一個屬性p的對象 o = Object.create({}, { p: { value: 42 } }) // 省略了的屬性特性默認爲false,因此屬性p是不可寫,不可枚舉,不可配置的: o.p = 24 o.p //42 o.q = 12 for (var prop in o) { console.log(prop) } //"q" delete o.p //false //建立一個可寫的,可枚舉的,可配置的屬性p o2 = Object.create({}, { p: { value: 42, writable: true, enumerable: true, configurable: true } });
這個 polyfill 涵蓋了主要的應用場景,它建立一個已經選擇了原型的新對象,但沒有把第二個參數考慮在內。對象
請注意,儘管在 ES5 中 Object.create
支持設置爲[[Prototype]]
爲null
,但由於那些ECMAScript5之前版本限制,此 polyfill 沒法支持該特性。繼承
if (typeof Object.create !== "function") { Object.create = function (proto, propertiesObject) { if (!(proto === null || typeof proto === "object" || typeof proto === "function")) { throw TypeError('Argument must be an object, or null'); } var temp = new Object(); temp.__proto__ = proto; if(typeof propertiesObject ==="object") Object.defineProperties(temp,propertiesObject); return temp; }; }