JavaScript中的Objects,JavaScriptObjects

來源:互聯網
上載者:User

JavaScript中的Objects,JavaScriptObjects
JavaScript中的Objects

在JavaScript中,建立Objects有兩種方式,declarative (literal) form和 constructed form。

首先,聲明式如下:

var myObj = {    key: value    // ...};

構造式如下:

var myObj = new Object();myObj.key = value;

聲明式與構造式建立的對象完全相同,只不過構造式的需要一個個地添加添加屬性,一般情況下我們都是採用聲明式的建立對象。

JavaScript中的原始類型

JavaScrip中有六種原始類型:

  • string
  • number
  • boolean
  • null
  • undefined
  • object

他們並不屬於物件類型,值得注意的是,null有時候被認為是物件類型,主要原因是typeof null的傳回值為object(該語言的bug),實際上,null屬於原始類型。

還有一種誤解

everything in JavaScript is an object

顯然這也是錯誤的。

物件類型中還有一些物件類型的子類型的( object sub-types),function是其子類型(專業術語稱之為callable object),在JavaScript被認作是第一等的(first class),相比一般對象,function具有調用屬性(callable behavior),還有一種物件類型的子類型為數組(Arrays ),相比一般對象,其內容更結構化。

JavaScript中還有一些內建對象的子類型,我們稱之為內建對象(built-in objects),有如下幾種:

  • String
  • Number
  • Boolean
  • Object
  • Function
  • Array
  • Date
  • RegExp
  • Error

這些內建對象表現出來的特性甚至與Java中的class的特性一致,實際上,它們都是內建函數(built-in functions),這些內建函數都被用作構造器(constructor ),關於JavaScript 中的構造器,

傳統的物件導向的語言中,構造器屬於class的特殊方法,當我們使用new執行個體化一個類時,其構造器被調用,JavaScript 中的構造器與此很不同,JavaScript 中的構造器只是一般的函數(functions ),其恰好在函數前面使用了new操作符,它們與class無關,也不是用來執行個體化一個類,它們只是一個很普通的函數,只不過被new操作符 控制 調用了而已,它們不是constructor functions,只是construction calls of functions而已。

var strPrimitive = "I am a string";typeof strPrimitive;                            // "string"strPrimitive instanceof String;                 // falsevar strObject = new String( "I am a string" );typeof strObject;                               // "object"strObject instanceof String;                    // true// inspect the object sub-typeObject.prototype.toString.call( strObject );    // [object String]

strPrimitive屬於原始類型,strObject 屬於物件類型,當我們如果要檢查strPrimitive的長度,擷取其內容時,我們需要String類型的對象類完成操作。

幸運的是,當我們將原始類型的string轉化(coerces )為物件類型的String時,這些操作都被自動完成了,因此,一般來說,我們並不需要建立物件類型的變數,只需建立其對應的原始類型的變數即可,在需要時,JavaScript會自動幫我們轉化為對應的物件類型。

var strPrimitive = "I am a string";console.log( strPrimitive.length );         // 13console.log( strPrimitive.charAt( 3 ) );    // "m"

null 和undefined沒有相應的物件類型,Date 類型沒有對應的原始類型,Object, Array, Function, 和RegExp,無論我們使用literal還是使用constructor方式構建,其均為物件類型。

Error對象我們一般很少建立,其都是在出現異常時自動建立。

一般來說,對象中的內容不一定儲存在對象內部,其主要依賴於瀏覽器的實現,很多情況下,他們並不儲存在對象容器中,真正儲存在對象中的是對象的屬性名稱,他們主要用來作為引用指向他們對應的值的地方。

var myObject = {    a: 2};myObject.a;     // 2myObject["a"];  // 2

使用 . 操作符的其名稱與使用[""]的區別是後者可以使用UTF-8/unicode相容的屬性名稱,如[“Super-Fun!”],而前者則不可以通過. 操作符獲得對應的屬性值。

對象的屬性名稱都是string類型,我們可以通過變數的值來作為指向對象屬性值的地址:

var wantA = true;var myObject = {    a: 2};var idx;if (wantA) {    idx = "a";}// laterconsole.log( myObject[idx] ); // 2

由於對象的屬性名稱都是sting類型,如果不是string類型,JavaScript首先將其轉化為string類型,我們在使用時要注意這一點:

var myObject = { };myObject[true] = "foo";myObject[3] = "bar";myObject[myObject] = "baz";myObject["true"];               // "foo"myObject["3"];                  // "bar"myObject["[object Object]"];    // "baz"

ES6中我們可以使用myObject[..]這種文法來計算出對象的屬性名稱:

var prefix = "foo";var myObject = {    [prefix + "bar"]: "hello",    [prefix + "baz"]: "world"};myObject["foobar"]; // hellomyObject["foobaz"]; // world

這種計算對象屬性名稱主要是用在Symbol(new primitive data type which has an opaque unguessable value, technically a string value)上,對象中的函數同樣也是不屬於對象本身,其擷取與屬性的擷取沒有什麼不同。

對於數組,我們需要注意的是,當我們向數組中添加屬性時,如果該屬性是數字類型的話,那麼將作為數組的元素添加到數組中,而不是像一般的屬性添加到數組對象中去:

var myArray = [ "foo", 42, "bar" ];myArray["3"] = "baz";myArray["a"]="a";myArray.length; // 4myArray[3];     // "baz"myArray.a;      //"a"

ES5中,對象的屬性可以通過 property descriptor來進行描述:

var myObject = {    a: 2};Object.getOwnPropertyDescriptor( myObject, "a" );// {//    value: 2,//    writable: true,//    enumerable: true,//    configurable: true// }

對象的屬性有三個特徵:writable, enumerable, 和configurable,他們的預設值如上例所示。我們可以Object.defineProperty(..)來為對象新添加一個屬性,或者修改對象屬性(如果是configurable的):

var myObject = {};Object.defineProperty( myObject, "a", {    value: 2,    writable: true,    configurable: true,    enumerable: true} );myObject.a; // 2

當writable=false,相當於其對象沒有setter方法:

var myObject = {};Object.defineProperty( myObject, "a", {    value: 2,    writable: false, // not writable!    configurable: true,    enumerable: true} );myObject.a = 3;myObject.a; // 2

如果在strict mode下,則會報錯:

"use strict";var myObject = {};Object.defineProperty( myObject, "a", {    value: 2,    writable: false, // not writable!    configurable: true,    enumerable: true} );myObject.a = 3; // TypeError

configurable=false是單向操作,無法復原:

var myObject = {    a: 2};myObject.a = 3;myObject.a;                 // 3Object.defineProperty( myObject, "a", {    value: 4,    writable: true,    configurable: false,    // not configurable!    enumerable: true} );myObject.a;                 // 4myObject.a = 5;myObject.a;                 // 5Object.defineProperty( myObject, "a", {    value: 6,    writable: true,    configurable: true,    enumerable: true} ); // TypeError

需要注意的一點是,當configurable=false時,我們可以配置writable的值從true到false,但是不能從false到true。

configurable=false還有一個作用就是阻止我們使用delete操作符刪除該屬性。

var myObject = {    a: 2};myObject.a;             // 2delete myObject.a;myObject.a;             // undefinedObject.defineProperty( myObject, "a", {    value: 2,    writable: true,    configurable: false,    enumerable: true} );myObject.a;             // 2delete myObject.a;myObject.a;             // 2

對於enumerable,主要是用來控制for..in迴圈中是否可顯示。

著作權聲明:本文為博主原創文章,未經博主允許不得轉載。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.