js中創(chuàng)建對象Object.create()和new object()的區(qū)別

Object.create()方法創(chuàng)建一個新對象,使用現(xiàn)有的對象來提供新創(chuàng)建的對象的 __proto __。

const person = {
  isHuman: false,
  printIntroduction: function () {
    console.log(`My name is ${this.name}. Am I human? ${this.isHuman}`);
  }
};

const me = Object.create(person);

me.name = "Matthew"; // "name" 這個屬性只被寫在me上, 沒有被寫在"person"上
me.isHuman = true; // 繼承的屬性可被重寫

me.printIntroduction();
// expected output: "My name is Matthew. Am I human? true"

語法:

Object.create(proto, [propertiesObject])

proto:新創(chuàng)建對象的原型對象。

propertiesObject: 可選。如果沒有指定為 undefined,則是要添加到新創(chuàng)建對象的可枚舉屬性(即其自身定義的屬性,而不是其原型鏈上的枚舉屬性)對象的屬性描述符以及相應(yīng)的屬性名稱。這些屬性對應(yīng)Object.defineProperties()的第二個參數(shù)。

返回值:一個新對象帶著指定的原型對象和屬性。
例外:如果propertiesObject參數(shù)是 null 或非原始包裝對象,則拋出一個 TypeError 異常。

例子:

// Shape - 父類(superclass)
function Shape() {
  this.x = 0;
  this.y = 0;
}

// 父類的方法
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.
}

// 子類續(xù)承父類
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.'

如果你希望能繼承到多個對象,則可以使用混入的方式。

function MyClass() {
     SuperClass.call(this);
     OtherSuperClass.call(this);
}

// 繼承一個類
MyClass.prototype = Object.create(SuperClass.prototype);
// 混合其它
Object.assign(MyClass.prototype, OtherSuperClass.prototype);
// 重新指定constructor
MyClass.prototype.constructor = MyClass;

MyClass.prototype.myMethod = function() {
     // do a thing
};

使用Object.create的propertyObject參數(shù)

var o;

// 創(chuàng)建一個原型為null的空對象
o = Object.create(null);


o = {};
// 以字面量方式創(chuàng)建的空對象就相當(dāng)于:
o = Object.create(Object.prototype);


o = Object.create(Object.prototype, {
  // foo會成為所創(chuàng)建對象的數(shù)據(jù)屬性
  foo: { 
    writable:true,
    configurable:true,
    value: "hello" 
  },
  // bar會成為所創(chuàng)建對象的訪問器屬性
  bar: {
    configurable: false,
    get: function() { return 10 },
    set: function(value) {
      console.log("Setting `o.bar` to", value);
    }
  }
});


function Constructor(){}
o = new Constructor();
// 上面的一句就相當(dāng)于:
o = Object.create(Constructor.prototype);
// 當(dāng)然,如果在Constructor函數(shù)中有一些初始化代碼,Object.create不能執(zhí)行那些代碼


// 創(chuàng)建一個以另一個空對象為原型,且擁有一個屬性p的對象
o = Object.create({}, { p: { value: 42 } })

// 省略了的屬性特性默認(rèn)為false,所以屬性p是不可寫,不可枚舉,不可配置的:
o.p = 24
o.p
//42

o.q = 12
for (var prop in o) {
   console.log(prop)
}
//"q"

delete o.p
//false

//創(chuàng)建一個可寫的,可枚舉的,可配置的屬性p
o2 = Object.create({}, {
  p: {
    value: 42, 
    writable: true,
    enumerable: true,
    configurable: true 
  } 
});

new object()

new 運算符創(chuàng)建一個用戶定義的對象類型的實例或具有構(gòu)造函數(shù)的內(nèi)置對象的實例。new 關(guān)鍵字會進(jìn)行如下的操作:

創(chuàng)建一個空的簡單JavaScript對象(即{});

鏈接該對象(即設(shè)置該對象的構(gòu)造函數(shù))到另一個對象 ;

將步驟1新創(chuàng)建的對象作為this的上下文 ;

如果該函數(shù)沒有返回對象,則返回this。

當(dāng)你執(zhí)行
var o = new Foo();

實際上執(zhí)行了
var o = new Object();
o.__proto__ = Foo.prototype;
Foo.call(o);

描述

  1. 通過編寫函數(shù)來定義對象類型。
  2. 通過 new 來創(chuàng)建對象實例。

創(chuàng)建一個對象類型,需要創(chuàng)建一個指定其名稱和屬性的函數(shù);對象的屬性可以指向其他對象,看下面的例子:

當(dāng)代碼 new Foo(...) 執(zhí)行時,會發(fā)生以下事情:

  1. 一個繼承自 Foo.prototype 的新對象被創(chuàng)建。
  2. 使用指定的參數(shù)調(diào)用構(gòu)造函數(shù) Foo,并將 this 綁定到新創(chuàng)建的對象。new Foo 等同于 Foo(),也就是沒有指定參數(shù)列表,Foo 不帶任何參數(shù)調(diào)用的情況。
  3. 由構(gòu)造函數(shù)返回的對象就是 new 表達(dá)式的結(jié)果。如果構(gòu)造函數(shù)沒有顯式返回一個對象,則使用步驟1創(chuàng)建的對象。(一般情況下,構(gòu)造函數(shù)不返回值,但是用戶可以選擇主動返回對象,來覆蓋正常的對象創(chuàng)建步驟)

你始終可以對已定義的對象添加新的屬性。例如,car1.color = "black" 語句給 car1 添加了一個新的屬性 color,并給這個屬性賦值 "black"。但是,這不會影響任何其他對象。要將新屬性添加到相同類型的所有對象,你必須將該屬性添加到 Car 對象類型的定義中。

你可以使用 Function.prototype 屬性將共享屬性添加到以前定義的對象類型。這定義了一個由該函數(shù)創(chuàng)建的所有對象共享的屬性,而不僅僅是對象類型的其中一個實例。下面的代碼將一個值為 nullcolor 屬性添加到 car 類型的所有對象,然后僅在實例對象 car1 中用字符串 "black" 覆蓋該值。詳見 prototype。

function Car() {}
car1 = new Car();
car2 = new Car();

console.log(car1.color);    // undefined
 
Car.prototype.color = "original color";
console.log(car1.color);    // original color
 
car1.color = 'black';
console.log(car1.color);   // black

console.log(car1.__proto__.color) //original color
console.log(car2.__proto__.color) //original color
console.log(car1.color)  // black
console.log(car2.color) // original color

如果你沒有使用 new 運算符, 構(gòu)造函數(shù)會像其他的常規(guī)函數(shù)一樣被調(diào)用, 并不會創(chuàng)建一個對象。在這種情況下, this 的指向也是不一樣的。

參見:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Operators/new
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Object/create

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 函數(shù)和對象 1、函數(shù) 1.1 函數(shù)概述 函數(shù)對于任何一門語言來說都是核心的概念。通過函數(shù)可以封裝任意多條語句,而且...
    道無虛閱讀 4,926評論 0 5
  • ??面向?qū)ο螅∣bject-Oriented,OO)的語言有一個標(biāo)志,那就是它們都有類的概念,而通過類可以創(chuàng)建任意...
    霜天曉閱讀 2,245評論 0 6
  • 第3章 基本概念 3.1 語法 3.2 關(guān)鍵字和保留字 3.3 變量 3.4 數(shù)據(jù)類型 5種簡單數(shù)據(jù)類型:Unde...
    RickCole閱讀 5,489評論 0 21
  • 如何開設(shè)社區(qū)便利店 總是不斷有朋友在問開一家便利店需要多少錢,如何開設(shè)? 答案其實不一,因為針對不同地區(qū)與所定位的...
    琉璃小鎮(zhèn)閱讀 616評論 0 0
  • 一個人狀態(tài)是自己去慢慢的調(diào)整的。 當(dāng)你調(diào)整好心態(tài)時一天會過的充實。 當(dāng)你有一個好的心情一天才會美好。 總而總之,每...
    小龍耶閱讀 172評論 0 2

友情鏈接更多精彩內(nèi)容