搜尋
首頁web前端js教程JavaScript高階程式設計(第3版)學習筆記6 初識js物件_基礎知識

在房子裡面可以放你想放的任意事物——如果你有足夠的美學造詣,你甚至可以弄一個房中房試試——當然,為了方便管理,我們會給房子裡存放的所有事物都會取上一個不重複的名字,例如醫藥房間裡的各種藥品名稱。在ECMAScript中,你可以在物件中存放任意你想放的數據,同樣,我們需要為存放的資料取一個名字──也就是物件的屬性名,再存放各種資料。再看看ECMA-262中物件的定義:無序屬性的集合,其屬性可以包含簡單資料類型值、物件或函數。

  進入對象,我開始有些激動了,說實話,讓我想起做這系列學習筆記的最初原因,就是因為該書對對象的深刻論述,讓我對JavaScript的認知從客戶端驗證小工具轉變成一門強大的物件導向腳本語言,但我現在也有點犯錯了,因為關於對象,有太多太多的東西需要去細化,一時也不知該從哪個點切入,比如要想深入理解對象,作用域、執行環境、閉包這些概念是肯定離不開的,但如果連對象的概念都沒說就開始執行環境和閉包,又感覺像是空中樓閣。不過又一想,也就釋然了,這畢竟只是自己的個人學習筆記,又不是什麼教科書,我大可以用自己喜歡的方式來做自己的筆記(事實上,在前面的篇章中,我就有意識的重複那些我認為有意思的地方,這就是我喜歡的一種方式),當然,我還是會盡量以一種易於理解的方式來做這些筆記。

物件類型

  和5種簡單資料類型(Undefined、Null、Boolean、Number、String)相對應,物件(Object)也是一種資料類型,只是這種數據類型比較特別,它不但可以像簡單數據類型一樣訪問通常的數據,而且可以將動作行為作為一種特殊的數據加以訪問。

1、物件實例

  每個資料型態都有對應的值,例如Undefined型別只有一個值undefined,而數字5是Number型別的一個值。對於物件類型,我們把值稱為物件實例,那麼物件類型都可以有哪些(值)實例呢?任一物件都是物件類型的值(實例),例如簡單型別包裝物件(Boolean、Number、String)就是物件類型的值(實例)。

2、物件字面量

  既然任一個物件都是物件類型的實例,那麼物件實例怎麼表示呢?或者說我們在交流過程中怎麼書寫出物件實例呢?簡單資料型別的值很好表示,例如用符號「5」表示數字5,符號「true」表示Boolean值true,這些稱為字面量,那麼,有沒有物件字面量呢?答案是肯定的,而物件字面量就是用一對大括號({})來表示的。例如:

複製程式碼 程式碼如下:

{
name:


{
name:'linjisong'
getName:function(){
return this.name;
}
} 複製程式碼


程式碼如下:


[{
name:'linjisong ',
age:29
},{
name:'oulinhai', age:23 }]
這裡一對中括號([])用來表示數組,這是一個包含了兩個物件的陣列。透過物件字面量和陣列字面量,形成了難以想像的強大表現力,事實上,流行的JSON資料格式就是基於此。

3、建立物件實例

  熟悉一般物件導向的朋友都知道,要建立一個類別的實例,首先要定義這個類,然後用new關鍵字來創建這個類別的實例(別和我說還可以使用反射,我的Java可學的不好…)。但是在ECMAScript中,根本沒有類別的概念,那麼,物件實例要怎麼創建呢?

  在ECMAScript中儘管沒有類,但是也有某種程度上類似的概念,承擔這個角色的就是函數,可以透過new操作符和函數來建立物件實例-每一個物件實例都有一個用於建立這個實例的函數。最基本的函數就是Object(),它是用來建立最一般物件的函數,其它的諸如Number()函數,可以用來建立Number物件的實例,Boolean()函數,可以用來建立Boolean物件的實例:
複製代碼 代碼如下:

var obj = new Object();//Object ()函數,建立最一般的物件實例
var num = new Number(1);//Number()函數,建立Number物件的實例
var boo = new Boolean(true);//Boolean( )函數,建立Boolean物件的實例
console.info(typeof num);//object
console.info(typeof Number(1));//number
console.info(typeof boo); //object
console.info(typeof Boolean(true));//boolean

(1)可以看到,要建立一個物件實例,首先需要有一個函數(稱為建構函數),這個函數使用new呼叫時就是建立物件實例,不使用new時只是通常意義上的函數呼叫(如果這個函數在內部傳回實例了,函數呼叫也可以建立物件)。

(2)所謂的內建物件其實也就是內建了一些創建物件實例的函數而已,不同的函數創建不同的內建物件。

(3)關於要不要使用new操作符,我的建議是使用,如果不使用new操作符,有些情況下結果會出乎你的意料之外,像上例中的第5 、7行,實際上並沒有創建對象,而只是普通的函數調用,這個調用的作用就是轉換資料型別。

(4)使用new建立物件實例時,如果呼叫建構函式不需要傳入參數,也可以省略後面的函式呼叫操作符(()),當然,這種特性也不是什麼值得宣揚的事情。

(5)如果需要建立自訂物件的實例,那麼首先也需要定義一個建構函數,然後使用new運算元呼叫建立實例。這裡要注意,如果忘了new的話,可能會污染全域環境:
複製程式碼 程式碼如下:

function Person(){//先定義一個用來建立物件實例的(建構)函式
this.name = 'linjisong';
this.age = 29;
}

var person = new Person();//呼叫(建構)函式建立物件實例
console.info(person.age);//29

try{
console. info(age);//為了示範忘記使用new的情況,這裡先輸出全域的age,由於未定義,拋出例外
}catch(e){
console.info(e);// ReferenceError
}
var person2 = Person();//忘記使用new的情況下,只是普通的函數調用,由於函數沒有返回,這裡person2就是undefined了
console.info(person2); //undefined
console.info(age);//29,沒有使用new,內部的this指向了全域作用域,因為可以在全域存取age了

要避免這種問題,可以修改建構子:
複製程式碼 程式碼如下:

function Person() {
if(this instanceof Person)
{
this.name = 'linjisong';
this.age = 29;
}else{
return new Person();
}
}
var person2 = Person();
console.info(person2.age);//29,可以存取person2的age了
console.info(age);/ /全域環境中沒有age的定義了,拋出異常


這個建構子先判斷this值是否為Person型,如果不是,就在內部使用new調用,以確保傳回的值一定是Person型別實例。這種方式使得重構建構函式成為了可能,也許Boolean()、Number()、String()在實作上就是使用了這種方式來區分是建構函式還是轉換函式。如果你在呼叫Object()時省略new的話,結果也能回傳對象,估計也是在後台做了類似處理,同樣的情況還有本文後部分要講的函數型別建構子Function()。

(5)可能有人會問,既然有物件字面量,何必要用這麼複雜的方式來建立物件實例呢,直接寫物件字面量就不完了?用物件字面量創建物件實例,根本沒有使用什麼函數,看來,上面的「每個物件實例都有一個用於創建這個實例的函數」的說法並不正確。

  首先第一個問題,的確,可以使用物件字面量來建立函數,而且也非常簡潔,這甚至也是我首先推薦的一種創建方式,但是用這種方式創建物件實例,只能創建單例的實例,對於需要創建多個相同類型的對象實例來說並不適用,然後第二個問題,用對象字面量創建對象,實際上並不是沒有相應的構造函數,只是構造函數為Object(),使用物件字面量,後台可能不會去呼叫new Object(),但建立的物件仍然有指向這個函數的屬性,這可以從下面程式碼輸出中得到驗證:
複製程式碼 程式碼如下:

var person = {};
console.info(person.constructor=== Object);//true

這裡的constructor是每個實例物件都有的屬性,用來保存建立這個物件實例的函數,這就是下面要講的。

4、物件屬性與方法

  每一種資料型別都有各自的共通性,例如Number型別值都有可以和另一個Number型別值相加的特性,同樣,物件類型的實例也有一些相同的特性,這些特性就體現在它們都包含下面的屬性和方法(方法實際上也是一種屬性,只是屬性的值類型是函數的話,我們也稱之方法):

类别 属性/方法 说明
属性 constructor 指向用于创建当前对象的函数
方法 hasOwnProperty(propertyName) 检查给定的属性是否在当前对象实例中
propertyIsEnumerable(propertyName) 检查给定的属性是否能够是使用for-in语句来枚举
isPrototype(object) 检查传入的对象是否是另一个对象的原型
toLocalString() 返回对象的字符串表示,该字符串与执行环境的地区相对应
toString() 返回对象的字符串表示
valueOf() 返回对象的字符串、数值或布尔值表示,通常与toString()方法返回值相同

註:在《JavaScript高級程式設計(第3版)》第35頁中的Constructor將首字母大寫了,應該是一個印刷錯誤。

屬性和方法的存取有兩種方式:

(1)使用點號(.):如person.name。

(2)使用方括號([]):如person[name],使用這種方式,方括號內部可以是一個變數或表達式,這使得可以存取名稱包含特殊符號的屬性和方法。

  透過結合for-in和這裡的hasOwnProperty (propertyName),我們就可以遍歷物件實例本身的屬性而不包括從原型鏈繼承而來的屬性了:
複製程式碼 程式碼如下:

for(var propertyName in object){
  if(object.hasif(object.haspperorm)>
    //循環處理
  }
}
陳述
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
JavaScript在行動中:現實世界中的示例和項目JavaScript在行動中:現實世界中的示例和項目Apr 19, 2025 am 12:13 AM

JavaScript在現實世界中的應用包括前端和後端開發。 1)通過構建TODO列表應用展示前端應用,涉及DOM操作和事件處理。 2)通過Node.js和Express構建RESTfulAPI展示後端應用。

JavaScript和Web:核心功能和用例JavaScript和Web:核心功能和用例Apr 18, 2025 am 12:19 AM

JavaScript在Web開發中的主要用途包括客戶端交互、表單驗證和異步通信。 1)通過DOM操作實現動態內容更新和用戶交互;2)在用戶提交數據前進行客戶端驗證,提高用戶體驗;3)通過AJAX技術實現與服務器的無刷新通信。

了解JavaScript引擎:實施詳細信息了解JavaScript引擎:實施詳細信息Apr 17, 2025 am 12:05 AM

理解JavaScript引擎內部工作原理對開發者重要,因為它能幫助編寫更高效的代碼並理解性能瓶頸和優化策略。 1)引擎的工作流程包括解析、編譯和執行三個階段;2)執行過程中,引擎會進行動態優化,如內聯緩存和隱藏類;3)最佳實踐包括避免全局變量、優化循環、使用const和let,以及避免過度使用閉包。

Python vs. JavaScript:學習曲線和易用性Python vs. JavaScript:學習曲線和易用性Apr 16, 2025 am 12:12 AM

Python更適合初學者,學習曲線平緩,語法簡潔;JavaScript適合前端開發,學習曲線較陡,語法靈活。 1.Python語法直觀,適用於數據科學和後端開發。 2.JavaScript靈活,廣泛用於前端和服務器端編程。

Python vs. JavaScript:社區,圖書館和資源Python vs. JavaScript:社區,圖書館和資源Apr 15, 2025 am 12:16 AM

Python和JavaScript在社區、庫和資源方面的對比各有優劣。 1)Python社區友好,適合初學者,但前端開發資源不如JavaScript豐富。 2)Python在數據科學和機器學習庫方面強大,JavaScript則在前端開發庫和框架上更勝一籌。 3)兩者的學習資源都豐富,但Python適合從官方文檔開始,JavaScript則以MDNWebDocs為佳。選擇應基於項目需求和個人興趣。

從C/C到JavaScript:所有工作方式從C/C到JavaScript:所有工作方式Apr 14, 2025 am 12:05 AM

從C/C 轉向JavaScript需要適應動態類型、垃圾回收和異步編程等特點。 1)C/C 是靜態類型語言,需手動管理內存,而JavaScript是動態類型,垃圾回收自動處理。 2)C/C 需編譯成機器碼,JavaScript則為解釋型語言。 3)JavaScript引入閉包、原型鍊和Promise等概念,增強了靈活性和異步編程能力。

JavaScript引擎:比較實施JavaScript引擎:比較實施Apr 13, 2025 am 12:05 AM

不同JavaScript引擎在解析和執行JavaScript代碼時,效果會有所不同,因為每個引擎的實現原理和優化策略各有差異。 1.詞法分析:將源碼轉換為詞法單元。 2.語法分析:生成抽象語法樹。 3.優化和編譯:通過JIT編譯器生成機器碼。 4.執行:運行機器碼。 V8引擎通過即時編譯和隱藏類優化,SpiderMonkey使用類型推斷系統,導致在相同代碼上的性能表現不同。

超越瀏覽器:現實世界中的JavaScript超越瀏覽器:現實世界中的JavaScriptApr 12, 2025 am 12:06 AM

JavaScript在現實世界中的應用包括服務器端編程、移動應用開發和物聯網控制:1.通過Node.js實現服務器端編程,適用於高並發請求處理。 2.通過ReactNative進行移動應用開發,支持跨平台部署。 3.通過Johnny-Five庫用於物聯網設備控制,適用於硬件交互。

See all articles

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

AI Hentai Generator

AI Hentai Generator

免費產生 AI 無盡。

熱工具

Dreamweaver Mac版

Dreamweaver Mac版

視覺化網頁開發工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

mPDF

mPDF

mPDF是一個PHP庫,可以從UTF-8編碼的HTML產生PDF檔案。原作者Ian Back編寫mPDF以從他的網站上「即時」輸出PDF文件,並處理不同的語言。與原始腳本如HTML2FPDF相比,它的速度較慢,並且在使用Unicode字體時產生的檔案較大,但支援CSS樣式等,並進行了大量增強。支援幾乎所有語言,包括RTL(阿拉伯語和希伯來語)和CJK(中日韓)。支援嵌套的區塊級元素(如P、DIV),

Safe Exam Browser

Safe Exam Browser

Safe Exam Browser是一個安全的瀏覽器環境,安全地進行線上考試。該軟體將任何電腦變成一個安全的工作站。它控制對任何實用工具的訪問,並防止學生使用未經授權的資源。

SAP NetWeaver Server Adapter for Eclipse

SAP NetWeaver Server Adapter for Eclipse

將Eclipse與SAP NetWeaver應用伺服器整合。