成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

再談JavaScript的數據類型問題

開發 前端
JavaScript的數據類型問題已經討論過很多次了,但許多人還有許多書仍然沿用著錯誤的、混亂的一些觀點,所以就再細講一回。

提及這個討論的原因在于argb同學在我的MSN博客(現在變成了wordproess,在這里)上的一段回復,又更早的起源則是兩年前關于《JavaScript征途》一書的大討論:

從“裝B被雷劈講起

——這個事就讓它過去了過去了吧。在討論中我提及到該書對JavaScript類型系統介紹的混亂,而argb翻出了這篇歷史文章,指我的混亂更混亂。于是我列了以下幾個問題給他:

我想很難很快速地解釋你的問題。那么,接著你的思路,我就問幾個問題好了:

1、函數是不是類型?是什么類型?

2、為什么說JavaScript中的函數是“第一型”的?

3、undefined如何“包裝成object”?即使你所說的是筆誤,那么對于“一切都是對象”的JavaScript,undefined是什么?

4、true與Boolean(true)在類型上有什么不同?

最后強調一下你的用詞問題:Undefined是類型,undefined是值,’undefined’是類型的名稱。此外,應留意JavaScript中存在著值類型與引用類型。

隨后argb的回復讓我覺得一切已經混亂到不得不講的地步。因為此前也沒有討論過《JavaScript征途》中的類型系統問題,于是這干脆就補個功課。下面認認真真地談談,也順便回復了argb同學。

再次感謝argb。若非如此,我這篇功課還要欠很久。有讀者與朋友們的關心,總是好的。答疑釋解,于人于已,皆成美事。

再談JavaScript的數據類型問題

首先我們談兩點體會。其一,JavaScript不是純粹的面向對象語言,它是混合語言,所以所謂“一切面向對象”既是宣傳用語,也是一種語言處理技巧。僅從“面向對象”來理解這個語言的類型,會犯很多錯誤。其二,ECMAScript的描述總是很準確而又遲滯于這門語言的發展。所以要理解一些現象,既要從JavaScript的歷史中去找,也要考慮到JavaScript現在的發展。ECMAScirpt是一個標準的、規范化的參考,但不是全部。

接下來說說類型。JavaScript既是過程式語言,也是面向對象的語言。這一定程度上,也表現為:它事實上有兩套類型系統。第一套類型系統是用typeof來識別,這是這個語言的基本類型系統,只有六種類型,即undefined、number、boolean、string、object與function。我一般也稱之為基礎類型系統。之所以稱為“基礎”,是因為第二套類型系統是以它為基礎,從object這一種類型中發展起來的,即對象類型系統。

對象類型系統用instanceof來識別,它相當于其它高級語言中的is操作/運算。面向對象的多態主要通過as和is來表達,對于JavaScript來說,由于是弱類型的(沒有強制類型檢查),所以不需要as。

對象類型系統與基礎類型系統存在映射關系,例如基礎類型的string影射到對象系統中的String。但這只是影射,所以本質上來說string類型不是String類型。兩者本質上不同。具體來說,undefined,string、number和boolean是“值類型”;object與function是“引用類型”。由于String、Number與Boolean在基礎類型中都屬于object類型,是Object()的子類,因此是引用類型。Function()也是引用類型。所有引用類型都可以看著Object()的子類,所以任意函數也是Object()的子類。例如"<匿名函數> instanceof Object"返回true。

undefined是值類型,它沒有對應的對象類型——我們通常可以稱之為Undefined類型,但它沒有對應的構造器。undefined只有一個值,即undefined。準確地說,undefined表明聲明(或產生)了但沒有值的變量。而Null也是一個類型,null是它的惟一值(按照語言規則,null也是一個關鍵字)。Null類型是對象類型,亦即是引用類型。所以Null與Undefined本質的不同,是它們分屬在不同的類型系統中,解釋著不同類型系統中的“無”的概念。一般來說,DOM中的某個屬性或成員如果無值,應該使用null;而JavaScript運算過程中如果出現無值,應該使用undefined。

上面強調要從“兩套類型系統”的角度來理解上述類型。而這兩個類型系統在JavaScript中是可以混用的,實現這一特性的技術被稱為“類包裝”。這是JavaScript對Java的主要借鑒,也是后來的.NET對Java的主要借鑒之一——類包裝也被稱為“裝箱”(以及“拆箱”)。JavaScript中的類包裝過程出現然屬性存取中,即“.運算符”或“[]運算符”。當這兩個運算符發現左操作數x是一個“值類型”數據時,將隱式地調用Object(x)過程將它轉為對象,因此

'abc'.length

這個運算實際上就等效于

Object('abc').length

最后,我們回到原始的問題上來。所以我說:

JavaScript 里面有6種基本類型,對象是其中一種,各種對象是“對象(object)”這一種類型中的子類(類型)。

是沒有什么錯誤的。而朱先生在他的書中說:

- JavaScript 語言只有 3 種最原始的數據類型:數值型、字符串型和布爾型

- JavaScript 還定義了幾個特殊的數據類型,如空類型(null)和未定義類型(undefined)。

- 基本數據類型按值傳送,而復雜數據類型按引用傳送。

這幾個觀點都不太靠譜。其一,這三種是原始的數據類型沒錯,但并不是“只有3種”,這個稍后一點我再說。其二,空類型與未定義類型這兩種說法都是錯的,應該是Null類型和Undefined類型——小寫的,是它們的值;首字母大寫才是它們的類型。其三,undefined也是按值傳遞的,然而在朱先生的分類里頭,就不知道如何歸屬。他起碼提到了:原始數據類型,特殊數據類型,值(傳遞的)類型,引用(傳遞的)類型。這樣復雜的分類,會更容易讓讀者混淆。

最后說一下“原始的數據類型”。這個用詞在ECMAScript里面有,稱為"primitive types",但這個概念主要是從“primitive values"里面引申出來的,而非單獨作為一個類型分類的依據——ECMAScript中只提到過一次primitive type,并且也沒有稱之為“types”。ECMAScript用“primitive values"來說明一些類型的原始值,例如Boolean Types具有原始值true/false。但這并沒有說明Boolean對象類型與值類型之間的差異或關系,例如不能表明true與Boolean(true)之間有什么不同。

ECMAScript中使用“primitive values",并陳述了這些原始值的定義,主要是ECMAScript要兼顧JavaScript語言的實現方案。在ECMAScript中相當大的一部分是在描述一個語言的實現,許多地方需要將一個對象轉換成“primitive values",或使用“primitive values"這樣的名詞來講述它的實際實現——但我必須強調,這與類型系統的定義與規劃沒什么關系。例如ECMA講述“屬性(property)”這一概念時,原文是:

“Properties are containers that hold other objects, primitive values, or functions. A primitive value is a member of one of the following built-in types: Undefined, Null, Boolean, Number, and String; an object is a member of the remaining built-in type Object; and a function is a callable object. A function that is associated with an object via a property is a method.”

翻譯過來就是:

屬性可以包括其它對象、原始值或函數。一個原始值(primitive value)是以下內建類型的一個成員(即一個值,value):Undefined, Null, Boolean, Number, 以及String;一個對象(object)是其它內建對象類型的一個成員(實例,instance),函數(function)是一個可調用的對象。如果一個函數作為一個對象的屬性,則我們稱為方法(method)。

上面的描述與“類型系統如何劃分”有什么關系嗎?沒有。關鍵在于上列5種原始值,都是可以跨語言來聲明或使用的。然而,要更細節地敘述這一點,需要完整地討論ECMAScript如何聲明與實現語言的全過程。

所以如果將“primitive value"作為類型系統來討論,就會相當地令人混亂了。這也是我一開始提出那幾個問題的原因。

最后,強調一點。function是類型。所以你提到:

函數不是類型,函數是函數,是類型(type)為object的一個分類(class)

大概是所有混亂的總和了。關于第一型(first-class data types)的問題就不再講了,以前已講得太多。大家自己翻吧。

原文:http://blog.csdn.net/aimingoo/article/details/6634977

【編輯推薦】

  1. 使用node.js進行服務器端JavaScript編程
  2. JavaScript實現頁面滾動圖片加載
  3. JavaScript內核之基本概念
  4. 10個對JavaScript開發者超級有用的工具
  5. 5個有趣的JavaScript代碼片段分享
責任編輯:陳貽新 來源: 周愛民的博客
相關推薦

2016-08-18 14:13:55

JavaScript基本數據引用數據

2010-10-08 15:11:28

JavaScript數

2021-12-03 15:24:45

Javascript數據類型

2018-11-15 09:45:47

JavaScript數據類型變量

2010-10-08 09:02:03

JavaScript基

2010-10-08 14:45:43

mysql中int

2017-02-27 08:34:09

JavaScript數據引用

2019-08-12 11:40:48

數據庫SQLite3數據類型

2020-12-29 07:56:23

JavaScript數據類型 primitive

2022-07-13 16:38:32

Python可變數據類型不可變數據類型

2022-08-12 16:12:34

JavaScript數據類型字符串

2021-02-25 07:08:30

JavaScript 前端面試題

2010-08-10 17:17:59

2022-03-07 13:58:30

JavaScript原始數據前端

2014-01-05 17:08:09

PostgreSQL數據類型

2021-02-26 14:33:04

Javascript數據類型前端

2010-06-17 16:27:26

WAP協議

2021-03-01 11:53:13

Javascript數據類型前端

2012-02-27 09:30:22

JavaScript

2010-07-22 17:57:40

點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 国产精品久久国产精品 | 日韩影院在线观看 | 草草影院ccyy | 日本黄色片免费在线观看 | 精精国产xxxx视频在线播放7 | 久久成人精品视频 | 一区欧美 | 91精品国产高清一区二区三区 | 91久久久久久久久久久久久 | 亚洲精品www久久久 www.蜜桃av | 国产精品久久久久无码av | 亚洲中午字幕 | 国产一区二区三区四区在线观看 | h片免费在线观看 | 日本在线免费看最新的电影 | 国产综合精品一区二区三区 | 精品一区二区三区在线观看国产 | 羞羞色在线观看 | 国产成人福利视频在线观看 | 日韩在线不卡视频 | 精品国产一区二区三区日日嗨 | 欧美视频在线免费 | 亚洲国产成人精品久久久国产成人一区 | 国产国拍亚洲精品av | 羞羞视频免费在线观看 | 国产日韩欧美激情 | 蜜桃av鲁一鲁一鲁一鲁 | 午夜成人免费视频 | 国产精品爱久久久久久久 | 成人在线观看网站 | 91在线视频精品 | 伊人网站| 精品中文在线 | 一区精品在线观看 | 巨大荫蒂视频欧美另类大 | 欧美精品a∨在线观看不卡 欧美日韩中文字幕在线播放 | 久久精品亚洲精品国产欧美 | 精品美女在线观看 | 国产视频第一页 | 一区二区中文 | 国产成人精品午夜视频免费 |