JavaScript物件導向-- 什麼是實體(Instance)?
上篇中提到我們需要用new去產生物件實體。
可以這麼想:
類別(Class): 就像模具
實體(Instance): 就像用模具做出的成品
以上兩者關係或用途為: (括號為類比、舉例)
1. 透過模具能生產出成品。
(可用蛋糕模具產生一個個蛋糕)
2. 但是模具非成品, 不能直接使用它。
(蛋糕模具本身不能食用)
3. 我們能直接使用成品。
(但是蛋糕能直接被食用)
4. 但是不能用成品去生產出另一個成品。
(蛋糕只能用來吃, 不能做為模具去生產另一個蛋糕)
從以上可知, 因為類別才具有原型, 才能產生實體; 而實體不具有原型, 所以不能用來產生新實體, 讓我們換用程式角度再看一次:
e.g.
function Foo() {
console.log(typeof Foo.prototype); // Object, 代表Class Foo存在原型, 且原型的資料 型別為Object
}
var a = new Foo(); // 在此產生名稱為a的實體
console.log(a.prototype); // undefined, 代表a不具有原型
console.log(a.__proto__ === Foo.prototype); // true, 因為a的__proto__指向Class Foo的prototype, 且可知Foo才有prototype, a則沒有。
繼續舉例:
e.g.
Array.push(); // Array.push isn't a function, 因為Class Array不能直接拿 來操作使用
var ary = new Array(); // 這個沒問題, 可透過類別產生新實體
ary.push(); // 這也沒問題, 實體可以直接拿來使用, ary.push() === ary.push(0), 會產生一個空的新陣列
var ary2 = new ary(); // ary isn't a constructor, 因為實體 ary不含原型, 所以沒有建 構式(constructor)。由此可知, 實體不能生產出另個實體
p.s. 不知會不會像我一樣產生一個疑問: __proto__ & prototype差在哪裡?
如果在將上面例子用瀏覽器查看一下:
console.dir(Foo); -->
function Foo() {}
-> prototype: Object (是Object是因function型別為Object)
-> constructor: function Foo()
console.dir(a); -->
Foo
-> __proto__: Object
->constructor: function Foo()
以上可看出, 只有Class Foo才具有prototype, 且只有prototype才含有constructor; 而實體
a因由Foo而來。本身尚未建立、新增自己物件的方法, 但它的__proto__是指向Class
Foo (__proto__: Object 是因Foo本身也是個Object)。一旦指向Foo, 便能在__proto__裡找
到Foo的constructor, 這作用就像路標, 讓實體a知道它是被Foo建立來的, 不會迷路。且就算
本身物件還未含方法, 也已具備由Class Foo而來的建構式(constructor)內容。
可以這麼想:
類別(Class): 就像模具
實體(Instance): 就像用模具做出的成品
以上兩者關係或用途為: (括號為類比、舉例)
1. 透過模具能生產出成品。
(可用蛋糕模具產生一個個蛋糕)
2. 但是模具非成品, 不能直接使用它。
(蛋糕模具本身不能食用)
3. 我們能直接使用成品。
(但是蛋糕能直接被食用)
4. 但是不能用成品去生產出另一個成品。
(蛋糕只能用來吃, 不能做為模具去生產另一個蛋糕)
從以上可知, 因為類別才具有原型, 才能產生實體; 而實體不具有原型, 所以不能用來產生新實體, 讓我們換用程式角度再看一次:
e.g.
function Foo() {
console.log(typeof Foo.prototype); // Object, 代表Class Foo存在原型, 且原型的資料 型別為Object
}
var a = new Foo(); // 在此產生名稱為a的實體
console.log(a.prototype); // undefined, 代表a不具有原型
console.log(a.__proto__ === Foo.prototype); // true, 因為a的__proto__指向Class Foo的prototype, 且可知Foo才有prototype, a則沒有。
繼續舉例:
e.g.
Array.push(); // Array.push isn't a function, 因為Class Array不能直接拿 來操作使用
var ary = new Array(); // 這個沒問題, 可透過類別產生新實體
ary.push(); // 這也沒問題, 實體可以直接拿來使用, ary.push() === ary.push(0), 會產生一個空的新陣列
var ary2 = new ary(); // ary isn't a constructor, 因為實體 ary不含原型, 所以沒有建 構式(constructor)。由此可知, 實體不能生產出另個實體
p.s. 不知會不會像我一樣產生一個疑問: __proto__ & prototype差在哪裡?
如果在將上面例子用瀏覽器查看一下:
console.dir(Foo); -->
function Foo() {}
-> prototype: Object (是Object是因function型別為Object)
-> constructor: function Foo()
console.dir(a); -->
Foo
-> __proto__: Object
->constructor: function Foo()
以上可看出, 只有Class Foo才具有prototype, 且只有prototype才含有constructor; 而實體
a因由Foo而來。本身尚未建立、新增自己物件的方法, 但它的__proto__是指向Class
Foo (__proto__: Object 是因Foo本身也是個Object)。一旦指向Foo, 便能在__proto__裡找
到Foo的constructor, 這作用就像路標, 讓實體a知道它是被Foo建立來的, 不會迷路。且就算
本身物件還未含方法, 也已具備由Class Foo而來的建構式(constructor)內容。
留言
張貼留言