單一物件
像所有值一樣,對象也具有屬性。實際上,您可以將一個對象視為一組屬性,其中每個屬性都是(鍵,值)對。鍵是一個字符串,值是任何JavaScript值。
在JavaScript中,您可以通過對象常量直接創(chuàng)建普通對象:
'use strict';
var jane = {
? ? name: 'Jane',
? ? describe: function () {
? ? ? ? return 'Person named '+this.name;
? ? }
};
前面的對象具有name和的屬性describe。您可以讀?。ā矮@取”)和寫入(“設(shè)置”)屬性:
> jane.name //獲取
簡
> jane.name ='John'; //設(shè)定
> jane.newProperty ='abc'; //自動創(chuàng)建的屬性
函數(shù)值屬性,例如如describe被稱為方法。它們用于this引用用于調(diào)用它們的對象:
> jane.describe()//調(diào)用方法
“叫約翰的人”
> jane.name ='Jane';
> jane.describe()
“人叫簡”
該in運營商檢查是否一個屬性是否存在:
>簡中的“ newProperty”
真正
>簡中的“ foo”
假
如果讀取的屬性不存在,則會得到值undefined。因此,前面的兩個檢查也可以這樣執(zhí)行:[ 2 ]
> jane.newProperty!==未定義
真正
> jane.foo!==未定義
假
該delete運營商刪除一個屬性:
>刪除jane.newProperty
真正
>簡中的“ newProperty”
假
任意屬性鍵
屬性鍵可以是任何字符串。到目前為止,我們已經(jīng)在對象文字中和點運算符之后看到了屬性鍵。但是,只有當它們是標識符時,您才能以這種方式使用它們(請參閱標識符和變量名)。如果要使用其他字符串作為鍵,則必須在對象文字中用引號將它們引起來并使用方括號來獲取和設(shè)置屬性:
> var obj = {'非標識符':123};
> obj ['非??標識符']
123
> obj ['not a identifier'] = 456;
方括號還允許您計算屬性的鍵:
> var obj = {hello:'world'};
> var x ='hello';
> obj [x]
'世界'
> obj ['hel'+'lo']
'世界'
提取方法
如果提取方法,則該方法將失去與對象的連接。該函數(shù)本身不再是方法,而是具有值(在嚴格模式下)。thisundefined
作為示例,讓我們回到先前的對象jane:
'use strict';
var jane = {
? ? name: 'Jane',
? ? describe: function () {
? ? ? ? return 'Person named '+this.name;
? ? }
};
我們describe要從中提取方法jane,將其放入變量中func,然后調(diào)用它。但是,這不起作用:
> var func = jane.describe;
> func()
TypeError:無法讀取未定義的屬性“名稱”
解決方案是使用所有功能都具有的方法bind()。它創(chuàng)建一個this始終具有給定值的新函數(shù):
> var func2 = jane.describe.bind(jane);
> func2()
“人叫簡”
方法內(nèi)部的功能
每個功能都有 它自己的特殊變量this。如果您將一個函數(shù)嵌套在一個方法內(nèi)部,這是很不方便的,因為您無法this從該函數(shù)訪問該方法。下面是一個示例,其中我們forEach使用一個函數(shù)來遍歷數(shù)組:
var jane = {
? ? name: 'Jane',
? ? friends: [ 'Tarzan', 'Cheeta' ],
? ? logHiToFriends: function () {
? ? ? ? 'use strict';
? ? ? ? this.friends.forEach(function (friend) {
? ? ? ? ? ? // `this` is undefined here
? ? ? ? ? ? console.log(this.name+' says hi to '+friend);
? ? ? ? });
? ? }
}
調(diào)用logHiToFriends會產(chǎn)生錯誤:
> jane.logHiToFriends()
TypeError:無法讀取未定義的屬性“名稱”
讓我們看一下解決此問題的兩種方法。首先,我們可以存儲this在另一個變量中:
logHiToFriends: function () {
? ? 'use strict';
? ? var that = this;
? ? this.friends.forEach(function (friend) {
? ? ? ? console.log(that.name+' says hi to '+friend);
? ? });
}
或者,forEach還有第二個參數(shù),可讓您提供以下值this:
logHiToFriends: function () {
? ? 'use strict';
? ? this.friends.forEach(function (friend) {
? ? ? ? console.log(this.name+' says hi to '+friend);
? ? }, this);
}
函數(shù)表達式通常在JavaScript中用作函數(shù)調(diào)用的參數(shù)。當您this從這些函數(shù)表達式之一進行引用時,請務(wù)必小心。
構(gòu)造函數(shù):對象工廠
到現(xiàn)在為止,您可能會認為 JavaScript對象只是從字符串到值的映射,這是JavaScript的對象文字所建議的一種概念,看起來像其他語言的map / dictionary文字。但是,JavaScript對象還支持一種真正面向?qū)ο蟮墓δ埽豪^承。本節(jié)未完全說明JavaScript繼承的工作原理,但向您展示了一種入門的簡單模式。如果您想了解更多,請查閱第17章。
除了是“真實的”函數(shù)和方法之外,函數(shù)在JavaScript中還扮演著另一個角色:如果通過運算符調(diào)用,它們將成為構(gòu)造函數(shù)(對象的工廠)new。因此,構(gòu)造函數(shù)大致類似于其他語言的類。按照約定,構(gòu)造函數(shù)的名稱以大寫字母開頭。例如:
// Set up instance data
function Point(x, y) {
? ? this.x = x;
? ? this.y = y;
}
// Methods
Point.prototype.dist = function () {
? ? return Math.sqrt(this.x*this.x + this.y*this.y);
};
我們可以看到構(gòu)造函數(shù)有兩個部分。首先,該函數(shù)Point設(shè)置實例數(shù)據(jù)。其次,屬性Point.prototype包含一個帶有方法的對象。前者數(shù)據(jù)特定于每個實例,而后者數(shù)據(jù)在所有實例之間共享。
要使用Point,我們通過運算符調(diào)用它:new
> var p =新Point(3,5);
>像素
3
> p.dist()
5.830951894845301
p是的實例Point:
> p instanceof點
真正