JavaScript中的對(duì)象屬性和應(yīng)用-創(chuàng)新互聯(lián)

本篇文章展示了JavaScript中的對(duì)象屬性和應(yīng)用,代碼簡明扼要容易理解,絕對(duì)能讓你眼前一亮,通過這篇文章的詳細(xì)介紹希望你能有所收獲。

為陽新等地區(qū)用戶提供了全套網(wǎng)頁設(shè)計(jì)制作服務(wù),及陽新網(wǎng)站建設(shè)行業(yè)解決方案。主營業(yè)務(wù)為網(wǎng)站建設(shè)、成都做網(wǎng)站、陽新網(wǎng)站設(shè)計(jì),以傳統(tǒng)方式定制建設(shè)網(wǎng)站,并提供域名空間備案等一條龍服務(wù),秉承以專業(yè)、用心的態(tài)度為用戶提供真誠的服務(wù)。我們深信只要達(dá)到每一位用戶的要求,就會(huì)得到認(rèn)可,從而選擇與我們長期合作。這樣,我們也可以走得更遠(yuǎn)!

JavaScript 中的對(duì)象概念的確很容易讓人困惑??聪旅嬉粋€(gè)例子:

var strPrimitive = "I'm mamacat";
typeof strPrimitive; // "string"
strPrimitive instanceof String; // false

var strObject = new String("I'm mamacat");
typeof strObject; // "object"
strObject instanceof String; // true

strPrimitive.substr(8, 3); // "cat"

同樣的字符串賦值到對(duì)象,一會(huì)兒是字符串類型一會(huì)兒是對(duì)象,而明明不是對(duì)象類型的變量還是可以使用對(duì)象屬性,為什么會(huì)這樣呢?

類型和內(nèi)置對(duì)象

JavaScript 中一共有六種主要(語言)類型,即 ,其中前五個(gè)基本類型都不是對(duì)象(對(duì) null 進(jìn)行 typeof 得到的是 "object",這是語言本身的 BUG)。而在此之外,則有許多特殊的對(duì)象子類型,例如數(shù)組、函數(shù)和內(nèi)置對(duì)象等。

有些內(nèi)置對(duì)象的名字看著和簡單基本類型一樣,就比如 String,Boolean,Object 之類。這些內(nèi)置對(duì)象從表現(xiàn)形式看就和別的面向?qū)ο笳Z言中的“類”概念差不多,而正如上篇文章所屬,它們實(shí)際使只是一些能被用來構(gòu)造一個(gè)對(duì)應(yīng)子類型的內(nèi)置函數(shù)而已(不要困惑,函數(shù)也是對(duì)象,這里并不矛盾)。于是就可以回到最初的例子,strObject 是由內(nèi)置函數(shù)/內(nèi)置對(duì)象 String 所構(gòu)造的變量,對(duì)應(yīng) String 子類型,所以它是一個(gè)對(duì)象,而 strPrimitive 則是一個(gè)原始字面值而已。

當(dāng)然,上面例子中最下面我們看上去對(duì) strPrimitive 調(diào)用了 substr() 函數(shù),這里則是因?yàn)?,JavaScript 引擎會(huì)在需要時(shí),把原始字面量轉(zhuǎn)換成對(duì)應(yīng)的對(duì)象,而轉(zhuǎn)換之后我們自然就可以使用屬性訪問對(duì)應(yīng)的方法了。

對(duì)象屬性

那么,就上方的例子而言,String 對(duì)象實(shí)例就會(huì)有 substr() 函數(shù)可以用,但根據(jù)之前的文章可以知道,這些“函數(shù)”本身并不屬于某個(gè)對(duì)象,而這些函數(shù)實(shí)質(zhì)是對(duì)應(yīng)對(duì)象的一個(gè)屬性。當(dāng)然,即便我們說某種類型的對(duì)象本身具備各種屬性,實(shí)際上這些屬性也多是各自獨(dú)立存在的,只不過以引用的形式關(guān)聯(lián)在了一起而已,這和之前了解的內(nèi)容也并不矛盾。這些被關(guān)聯(lián)起來的東西,被稱為對(duì)象的 屬性。

對(duì)象的復(fù)制

插播一條快報(bào),盡管之前的文章提到過,上方也又一次反復(fù)強(qiáng)調(diào)過屬性只是以引用的形式關(guān)聯(lián)起來的獨(dú)立存在,我們有時(shí)仍然會(huì)“理所應(yīng)當(dāng)”的認(rèn)為屬性是對(duì)象的一部分,而最容易因此踩坑的地方之一就是對(duì)象的復(fù)制了。仔細(xì)思考即可知道,當(dāng)我們復(fù)制對(duì)象時(shí),由于其屬性本身只是引用關(guān)聯(lián),故“復(fù)制”得到的對(duì)象所包含的屬性引用指向的和原本對(duì)象的屬性引用其實(shí)還是同一個(gè)位置:

var ori = { a : 1};
var ori_copy = ori;
ori.a = 61;
ori_copy.a; // 61

顯然這很可能和我們的期望不一樣,而我們想要真正的拷貝對(duì)象則沒有完美適用性的方案,很多時(shí)候的常規(guī)做法則是把對(duì)象序列化一下,然后再以此反序列化得到新的對(duì)象來實(shí)現(xiàn)對(duì)象的拷貝(比如使用 json)。ES6 中新增了 Object.assign() 來進(jìn)行對(duì)象的淺拷貝,做法是把對(duì)象的所有可枚舉屬性等號(hào)賦值到新對(duì)象中。不過仍需注意的是,等號(hào)賦值并不會(huì)賦值屬性的元信息(屬性描述符,后述),在需要的情況下應(yīng)當(dāng)特別留意。

屬性訪問和數(shù)組

訪問對(duì)象所關(guān)聯(lián)的屬性的方式即通過 . 或者 [] 操作符進(jìn)行訪問,obj.a 和 obj["a"] 訪問的屬性實(shí)質(zhì)上是一樣的,而這兩種訪問形式的區(qū)別也只有訪問的屬性名稱里能不能有奇怪的符號(hào)而已。[] 操作符內(nèi)扔的是個(gè)字符串,實(shí)際上屬性名也永遠(yuǎn)都是字符串。當(dāng)然,這個(gè)概念可能比較意外的就是,數(shù)組的下標(biāo)訪問其實(shí)并不是例外,數(shù)字還是被轉(zhuǎn)換成了字符串才被使用的。

// 對(duì)象的屬性訪問:
var tejilang = {1 : "Teji Wolf"};
tejilang instanceof Array; // false
tejilang["1"]; // "Teji Wolf"
tejilang[1]; // "Teji Wolf"

// 這回保證它是 Array
var macat = ["codingcat"];
macat instanceof Array; // true
macat.length; // 1
macat[0]; // "codingcat"
macat["0"]; // "codingcat"
macat.length = 20;
macat; // (20) ["codingcat", empty × 19]

數(shù)組下標(biāo)既然不屬例外情況,那數(shù)組對(duì)象必然有其它屬性控制數(shù)組本身的行為,例如上例中,macat 數(shù)組的長度就是 length 屬性所體現(xiàn)的,通過修改它的值也就改變了對(duì)象本身對(duì)外的表現(xiàn)形式。當(dāng)然,由于數(shù)組本身就是對(duì)象,所以我們還是可以把數(shù)組當(dāng)鍵值對(duì)來用,只是這種做法通常是沒有意義且會(huì)讓人感到困惑的。JavaScript 引擎通常都根據(jù)對(duì)象的類型做了不同程度的優(yōu)化,故除了代碼邏輯可讀性外,合理的使用也是多少可以改善性能的。

能夠通過字符訪問屬性還是存在一些別的好處的,比如 ES6 的可計(jì)算屬性名。當(dāng)然 ES6 不在本文的關(guān)注范圍內(nèi),所以這里就不再討論了。

屬性描述符

有時(shí)我們可能不希望某個(gè)屬性被隨意修改,有時(shí)候我們需要額外配置一些屬性的信息,自 ES5 起,所有的屬性就都具備了“屬性描述符”(Property Descriptor)來控制屬性本身的這些元信息。

數(shù)據(jù)描述符

來看這個(gè)例子:

var chris = {};
Object.defineProperty(chris, "IQ", {
    value: 228,
   writable: false,
    configurable: true,
    enumerable: true
});
chris.IQ = 61; // 靜默失敗了,如果是嚴(yán)格模式則會(huì) TypeError
chris.IQ; // 228

通過 defineProperty 可以對(duì)一個(gè)對(duì)象的屬性配置其對(duì)應(yīng)的屬性描述符(元信息),而屬性描述符則包含訪問描述符和數(shù)據(jù)描述符,上面的例子中,defineProperty 的第三個(gè)參數(shù)就定義了數(shù)據(jù)的若干數(shù)據(jù)描述符,其中 writable 表示可寫,表示屬性是否可配置(注意,修改成不可配置是單向操作),則表示屬性是否應(yīng)當(dāng)出現(xiàn)在枚舉中,比如 中。

顯然我們可以通過屬性描述符實(shí)現(xiàn)對(duì)屬性的保護(hù),而同時(shí)也存在一些方便函數(shù)來做近似的事。如 會(huì)保留原有屬性但禁止添加新屬性, 會(huì)密封對(duì)象,在禁止添加新屬性的基礎(chǔ)上把原有屬性標(biāo)記為不可配置,Object.freeze() 會(huì)凍結(jié)對(duì)象,即在密封的基礎(chǔ)上把數(shù)據(jù)訪問屬性標(biāo)記為不可寫。

[[Get]], [[Put]] 和訪問描述符

在我們?cè)L問和賦值一個(gè)對(duì)象的屬性時(shí),實(shí)際上是通過 [[Get]] 和 [[Put]] 操作進(jìn)行的,例如屬性訪問時(shí),[[Get]] 會(huì)先找有沒有這個(gè)屬性,如果沒有則會(huì)遍歷對(duì)象的 [[Prototype]] 鏈(原型鏈,這次不談這個(gè)概念)來找,實(shí)在找不到則返回 undefined 。而這個(gè)行為實(shí)際是允許我們通過設(shè)置 getter (get())和 setter (set())函數(shù)來改變的,它們被稱為 訪問描述符。

當(dāng)我們提供訪問描述符時(shí),對(duì)應(yīng)的訪問操作就不再受到 和 屬性的影響了,另外需要注意的是,盡管它們也是屬性描述符,但定義 getter 和 setter 并不要求一定要通過 設(shè)置:

var obj = {
    get a() { // 給 a 屬性定義 getter
        return this._a_;
    },
    set a(val) { // a 屬性的 setter
        this._a_ = val * 2;
    }
}

obj.a = 2;
obj.a; // 4

屬性存在性

因?yàn)閷傩缘闹狄部赡苁?undefined,不存在的屬性直接訪問得到的也是 undefined,所以直接通過簡單的屬性訪問是無法區(qū)分是否存在的,這時(shí)我們即可通過 in 或者 hasOwnProperty() 檢查屬性是否存在對(duì)象中了:

var obj = {a : 2};
"a" in obj; // true
obj.hasOwnProperty("a"); // true

盡管仍沒有講到原型鏈的概念,這里仍然應(yīng)注意,in 操作符會(huì)檢查原型鏈中是否存在屬性,而 hasOwnProperty 則不會(huì)。另外在一些情況下,有的對(duì)象會(huì)沒有 hasOwnProperty 這個(gè)屬性(此處不提原因),這時(shí)可以用過 Object.prototype.hasOwnProperty.call(objName, propertyName) 來實(shí)現(xiàn)檢查。

看完上述內(nèi)容,你們對(duì)JavaScript中的對(duì)象屬性和應(yīng)用的更了解了嗎?如果還想學(xué)到更多技能或想了解更多相關(guān)內(nèi)容,歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道,感謝各位的閱讀!

另外有需要云服務(wù)器可以了解下創(chuàng)新互聯(lián)scvps.cn,海內(nèi)外云服務(wù)器15元起步,三天無理由+7*72小時(shí)售后在線,公司持有idc許可證,提供“云服務(wù)器、裸金屬服務(wù)器、高防服務(wù)器、香港服務(wù)器、美國服務(wù)器、虛擬主機(jī)、免備案服務(wù)器”等云主機(jī)租用服務(wù)以及企業(yè)上云的綜合解決方案,具有“安全穩(wěn)定、簡單易用、服務(wù)可用性高、性價(jià)比高”等特點(diǎn)與優(yōu)勢(shì),專為企業(yè)上云打造定制,能夠滿足用戶豐富、多元化的應(yīng)用場景需求。

當(dāng)前文章:JavaScript中的對(duì)象屬性和應(yīng)用-創(chuàng)新互聯(lián)
路徑分享:http://muchs.cn/article30/pggso.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供定制網(wǎng)站、網(wǎng)站策劃、響應(yīng)式網(wǎng)站、自適應(yīng)網(wǎng)站域名注冊(cè)、App設(shè)計(jì)

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)

成都定制網(wǎng)站建設(shè)