1. 程式人生 > >Constructor&object 的聯絡與區別

Constructor&object 的聯絡與區別

constructor&object 的聯絡與區別

建構函式與物件

建構函式是類中的特殊成員函式,用於為物件分配記憶體。它可用於為資料成員提供值。建立物件時將呼叫建構函式。它與類具有相同的名稱。建構函式不返回任何值。

建構函式是生成物件的模板,一個建構函式可以生成多個物件,每個物件都有相同的結構。 建構函式的缺點就是,每當你例項化兩個物件時,需要呼叫兩次建構函式的某一個方法,這帶來的壞處就是佔用記憶體,而且沒必要。
其次,為了解決建構函式的屬性和方法無法被物件例項所共享的問題,我們可以把需要共享的屬性和方法放在原型(prototype)物件上。原型物件上的所有屬性和方法,都會被物件例項所共享。對於建構函式來說,prototype是作為建構函式的屬性;對於物件例項來說,prototype是物件例項的原型物件。所以prototype即是屬性,又是物件。
然後,除了undefined和null之外,每一個數據型別都可以看成一個物件,每一個物件都有它的原型。所有一切物件的原型頂端,都是Object.prototype,即Object建構函式的prototype屬性指向的那個物件。當然,Object.prototype物件也有自己的原型物件,那就是沒有任何屬性和方法的null物件,而null物件沒有自己的原型。
原型鏈的特點有:
a:讀取物件的某個屬性時,JavaScript引擎先尋找物件本身的屬性,如果找不到,就到它的原型去找,如果還是找不到,就到原型的原型去找。如果直到最頂層的Object.prototype還是找不到,則返回undefined。
b:如果物件自身和它的原型,都定義了一個同名屬性,那麼優先讀取物件自身的屬性,這叫做“覆蓋”(overiding)。
c:一級級向上在原型鏈尋找某個屬性,對效能是有影響的。所尋找的屬性在越上層的原型物件,對效能的影響越大。如果尋找某個不存在的屬性,將會遍歷整個原型鏈。
再次,constructor屬性是原型物件上的一個屬性,可以被所有例項物件所共享。要注意的是,prototype是建構函式的屬性,而constructor則是建構函式的prototype屬性所指向的那個物件,也就是原型物件的屬性。由於constructor屬性是一種原型物件和建構函式的關係,所以在修改原型物件的時候,一定要注意constructor的指向問題。
最後,instanceof運算子返回一個布林值,用於判斷物件是否為某個建構函式的例項。

  任何函式都是建構函式,如果通過new就可以得到一個物件。通過函式不同的上下文呼叫分下面幾種:
(1). 當在一個函式呼叫之前有new關鍵字,則上下文為新建的物件;
//任何函式可以new 建立一個物件
(2). 當一個函式使用call或者apply呼叫時,給定的第一個引數即為上下文;
//構造方法中可以寫成員方法。然後通過物件來呼叫
(3). 否則,如果一個函式作為一個物件的屬性(obj.func)或者obj['func'])來呼叫時,它就把該物件作為上下文來執行;
//上邊new fun2()沒意義,直接 fun2()呼叫,這裡在全域性上下文執行
(4)如果與上述幾條都不符的話,則函式將在全域性上下文中執行。

Constructor:是用於建立和初始化類中建立的一種特殊方法。constructor屬性返回對建立此物件的陣列函式的引用。 

 語法

object.constructor

constructor([arguments])

 { ... }

派生類建構函式:

Constructor(.....args){

Super(...args);

}

 

在一個類中只能有一個名為 “constructor” 的特殊方法。 一個類中出現多次建構函式 (constructor)方法將會丟擲一個 SyntaxError 錯誤。

在一個構造方法中可以使用super關鍵字來呼叫一個父類的構造方法。

如果沒有顯式指定構造方法,則會新增預設的 constructor 方法。

如果不指定一個建構函式(constructor)方法, 則使用一個預設的建構函式(constructor)。

<script type="text/javascript">

var test=new Array();

if (test.constructor==Array)

{

document.write("This is an Array");

}

if (test.constructor==Boolean)

{

document.write("This is a Boolean");

}

if (test.constructor==Date)

{

document.write("This is a Date");

}

if (test.constructor==String)

{

document.write("This is a String");

}

</script>

輸出:

This is an Array

Object:object是js自帶的函式物件,可以有屬性和方法。

在定義以後,不能在使用new建立物件例項,可以複製給其他變數,多個變數同時引用一個物件,或者克隆物件。具有多型性,無法繼承,除非用複製的方式來實現

(1)Object.assign()

可以用作物件的複製

var obj = { a: 1 };

var copy = Object.assign({}, obj);

console.log(copy); // { a: 1 }

可以用作物件的合併 

var o1 = { a: 1 };

var o2 = { b: 2 };

var o3 = { c: 3 };

var obj = Object.assign(o1, o2, o3);

console.log(obj); // { a: 1, b: 2, c: 3 }

console.log(o1);  // { a: 1, b: 2, c: 3 }, 注意目標物件自身也會改變。

(2)Object.is() 

Object.is('haorooms', 'haorooms');     // true

Object.is(window, window);   // true

Object.is('foo', 'bar');     // false

Object.is([], []);           // false

var test = { a: 1 };

Object.is(test, test);       // true

Object.is(null, null);       // true

// 特例

Object.is(0, -0);            // false

Object.is(-0, -0);           // true

Object.is(NaN, 0/0);         // true

(3)Object.keys()

這個方法會返回一個由給定物件的自身可列舉屬性組成的陣列,陣列中屬性名的排列順序和使用 for...in 迴圈遍歷該物件時返回的順序一致 (兩者的主要區別是 一個 for-in 迴圈還會列舉其原型鏈上的屬性)。

/* 類陣列物件 */

var obj = { 0 : "a", 1 : "b", 2 : "c"};

alert(Object.keys(obj));

// 彈出"0,1,2"

/* 具有隨機鍵排序的陣列類物件 */

var an_obj = { 100: 'a', 2: 'b', 7: 'c' };

console.log(Object.keys(an_obj));

// console: ['2', '7', '100']

(4)Object.create() 

Object.create(proto, [ propertiesObject ])

第二個引數是可選的,主要用於指定我們建立的物件的一些屬性,

例:ar o;

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) }

}})

 

// 建立一個以另一個空物件為原型,且擁有一個屬性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 } });