JavaScript 語言核心(6)鍵值聚合體的物件
|
JavaScript 語言核心(5)操弄數值的運算子 << 前情 在 JavaScript 中,物件是 var obj = new Object(); 實際上,現在已經很少人這麼撰寫了,使用物件實字(Object literal)語法就可以建立一個物件: var obj = {};
兩者的作用相同,物件實字寫法顯然較有效率。在 JavaScript 中,每個物件都可以是獨一無二,不一定是由其建構式來規範,這能力稱為物件個性化(Object individuation),你可以隨時為物件新增特性(Properties),也可以隨時用 > var obj = {};
undefined
> obj.x = 10;
10
> obj.x;
10
> delete obj.x;
true
> obj.x;
undefined
>
若刪除成功, > var arr = []; undefined > arr.length; 0 > delete arr.length; false > 附帶一提的是, 如果事先知道物件的特性,可以使用物件實字一併建立。例如: > var obj = {
... x : 10,
... y: 20
... };
undefined
> obj.x;
10
> obj.y;
20
>
想要知道物件上有哪些自定義特性,可以使用 > for(var prop in obj) {
... console.log(prop);
... console.log(typeof prop);
... }
x
string
y
string
undefined
> 'x' in obj;
true
>
由以上也可以得知,每個特性名稱其實是字串型態,這也說明了,如果想用 事實上,點運算子( > var obj = {};
undefined
> obj['x'] = 10;
10
> obj.x;
10
> obj['x'];
10
>
JavaScript 的物件本質上,其實是個特性與值的群集(Collection),要比喻的話,有點像是 Java 中的 > var obj = {
... x : 10,
... y : 20
... };
undefined
> for(var prop in obj) {
... console.log(prop + ': ', obj[prop]);
... }
x: 10
y: 20
undefined
>
使用 > var obj = {
... 'openhome.cc': 'OpenHome',
... };
undefined
> obj.openhome.cc;
TypeError: Cannot read property 'cc' of undefined
at repl:1:13
at REPLServer.self.eval (repl.js:110:21)
at repl.js:249:20
at REPLServer.self.eval (repl.js:122:7)
at Interface.<anonymous> (repl.js:239:12)
at Interface.EventEmitter.emit (events.js:95:17)
at Interface._onLine (readline.js:202:10)
at Interface._line (readline.js:531:8)
at Interface._ttyWrite (readline.js:760:14)
at ReadStream.onkeypress (readline.js:99:10)
> obj['openhome.cc'];
'OpenHome'
> delete obj['openhome.cc'];
true
> 'openhome.cc' in obj;
false
>
除了使用 > var obj = {};
undefined
> obj.x ? 'has x' : 'has no x';
'has no x'
> obj.x = 10;
10
> obj.x ? 'has x' : 'has no x';
'has x'
>
特性偵測也可以與 function doSome(option) {
return {
x : option.x || 1,
y : option.y || 2,
z : option.z || 3
};
}
function log(obj) {
for(var p in obj) {
console.log(p + ': ' + obj[p]);
}
}
var processed = doSome({
x : 10,
y : 20
});
log(processed);
在上例中, x: 10 y: 20 z: 3 JavaScript 是個弱型別語言,在需要將物件轉為數值的場合,會呼叫 > var obj = {
... valueOf : function() {
..... return 100;
..... }
... };
undefined
> 100 + obj;
200
> obj + 200;
300
> obj > 100;
false
> obj >= 100;
true
>
在需要將物件轉換為字串的場合,則會呼叫 > var caterpillar = {
... name : 'Justin Lin',
... url : 'openhome.cc',
... toString : function() {
..... return '[name: ' + this.name + ', url: ' + this.url + ']';
..... }
... };
undefined
> 'My info: ' + caterpillar;
'My info: [name: Justin Lin, url: openhome.cc]'
>
在上例中,若透過 在JavaScript中, > var man1 = {
... name : 'Justin Lin',
... url : 'openhome.cc',
... equals : function(other) {
..... return (this.name === other.name) && (this.url === other.url);
..... }
... };
undefined
> var man2 = {
... name : 'Justin Lin',
... url : 'openhome.cc',
... equals : function(other) {
..... return (this.name === other.name) && (this.url === other.url);
..... }
... };
undefined
> man1 === man2;
false
> man1.equals(man2);
true
>
在上例中,兩個物件的 function equals(other) {
return (this.name === other.name) && (this.url === other.url);
}
var man1 = {
name : 'Justin Lin',
url : 'openhome.cc',
equals : equals
};
var man2 = {
name : 'Justin Lin',
url : 'openhome.cc',
equals : equals
};
var man3 = {
name : 'Justin Lin',
url : 'openhome.cc',
equals : equals
};
console.log(man1.equals(man2)); // true
console.log(man1.equals(man3)); // true
實際上,如果你知道如何使用函式定義建構式,並瞭解運用原型鏈(Prototype chain)實現繼承,上頭的需求可以改為以下的方式: function Man(name, url) {
this.name = name;
this.url = url;
}
Man.prototype.equals = function(other) {
return (this.name === other.name) && (this.url === other.url);
};
var man1 = new Man('Justin Lin', 'openhome.cc');
var man2 = new Man('Justin Lin', 'openhome.cc');
var man3 = new Man('Justin Lin', 'openhome.cc');
console.log(man1.equals(man2));
console.log(man1.equals(man3));
至於為何可以這麼做,會留在之後說明函式時再來討論。 在 ECMAScript 5 的嚴格模式中,不能對一些內建特性做 在嚴格模式下,不允許在使用物件實字建立物件時做重複的特性定義。例如,以下會引發 'use strict';
var obj = {
x : 10,
x : 20,
y : 30
};
EMCAScript 5 之後,在 |

Java 學習之路





