搜尋
首頁web前端js教程深入了解JS中的原始類型(primitive type)

深入了解JS中的原始類型(primitive type)

JavaScript中的原始型別(primitive type)包含Undefined、Null、Number、Boolean和String,其他變數皆為參考型別,也就是Object Type。原始型別保存位置是“棧內存”,而引用型別保存在“堆內存”中,但通常JavaScript中對變數的使用,並不太關心變數在記憶體中的位置。

「typeof」運算子用以取得變數的值的資料型態。 typeof可以接受變數名或字面量值作為操作數,傳回一個描述變數類型資訊的字串。要注意的是,typeof的回傳值與JavaScript中的型別並不是一一對應的:

  • #「undefined」—變數值未定義

  • “number” ——變數值是數值

  • “boolean” ——變數值是布林值

  • “string” ——變數值是字串

  • “object” ——變數值是物件或null

  • “function” ——變數值是函數

另外,typeof是一個像( ,-)一樣的操作符,而不是函數,雖然形如“typeof(12)”的用法不會產生錯誤,但對於操作符來說「typeof 12」才是合適的使用方法。

1、undefined和null

Undefined Type在ECMA-262文件中的定義是:

The Undefined type has exactly one value, called undefined. Any variable that has not been assigned a value has the value undefined.

##Undefined類型只有一個唯一的值“undefined”,變數的值為undefined意味著變數沒有被初始化。對於尚未使用var宣告的變量,使用它會產生錯誤,但使用typeof運算子會傳回「undefined」:

var foo;
alert(foo);        // undefined
alert(bar);        // 错误
alert(typeof foo); // undefined
alert(typeof bar); // undefined

undefined被實作為一個全域變數(而不是像null一樣的字面值),它的值是“未定義”。在ECMAScript 3中,undefined可以被賦予其它值,在ECMAScript 5中已被修正為唯讀的。

Null Type 也只有一個值null,用來表示「空值」。多數程式語言中的都有類似null、nil等用來表示空值的字面量。但與其他程式語言不同的是,JavaScript並沒有使用null表示未初始化的變數的值(由undefined表示)。

null的邏輯意義是表示一個空物件指標。 JavaScript中通常意義的物件並不包括簡單資料類型,所以邏輯上null表示變數指向了一個空值的Object類型(不是字面量「{}」)。

基於這個原因,便可理解為什麼使用typeof操作符取得null值的型別會得到「object」了。 JavaScript裡null值對Object類型的意義,類似0對Number類型,「」對於String類型。

undefined和null都用來描述“空值”,但在邏輯意義上,undefined比null要更為“底層”一些。一般情況下,不需要顯示的把變數值指定為undefined。

而對於一個意在保存Object但還沒有真正指向一個物件的變量,則應該把變數值設為null,體現null作為空物件指標的作用並且與undefined區分開來。

2、數值

ECMAScript使用了簡化的數字模型。它只有一個數字型別Number,而沒有分離出單獨的整數型別。在實作上,Number類型採用了IEEE 754標準定義的64位元雙精度浮點數格式。

64位元的浮點數格式中,52位元用來表示尾數,11位元表示指數,1位元符號。因此在表示整數時,JavaScript能夠表示的整數範圍在-Math.pow(2,53)和Math.pow(2,53)之間,超過這個範圍,低位數字的精度便無法保證了。

var n = Math.pow(2,53); // 9007199254740992
alert(n === n + 1);     // true, 9007199254740992 + 1得到的值还是9007199254740992

在實際的Web開發中,若需要在後台(如Java)傳遞一個Long Int類型給Javascript處理,很可能JavaScript把JSON資料解析為Number型別後,得到的結果並不是你想要的:它的後面幾位數字發生了變化。

JavaScript使用浮點數數值運算,因此小數部分會出現精確度問題,這跟所有其他採用IEEE 754標準格式表示浮點數的程式語言一樣。避免在程式碼中出現對小數部分的相等判斷。 (整數部分是精確的)

var a = 0.1;
var b = 0.2;
alert(a + b === 0.3); // false

如果數值超過了JavaScript所能表示數字上限(overflow),將自動轉換為代表無窮大的Infinity(或-Infinity,負無窮)值;如果數值無限接近0並且超過JavaScript表示範圍(underflow),將被設定為0(或-0,同0)。 JavaScript不會出現溢位錯誤(包括被零整除的時候)。

var a = Number.MAX_VALUE * 2;          //Infinity
var b = Number.MIN_VALUE / 2;          //0
var c = 1 / 0;                         //Infinity or NaN, 依JS执行环境不同
var d = 0 / 0;                         // NaN

Number型別定義了一個特殊的值NaN,即not-a-number。 NaN的意義代表一個本來就該得到數值的地方沒有得到任何數值。任何使用NaN做運算元的算術運算,都會得到NaN。

另外NaN也是唯一一个使用对自身进行相等判断会得到false的数值。NaN的这个怪异之处破坏了JavaScript运算符的对称性。如果在代码中需要通过比较数值大小进行分支判断,就需要注意可能出现NaN的情况,因为使用NaN与其他数值进行大小比较总会得到false,而这可能不是你想要的结果。

var a = 10;   
a = a - "not number"         // NaN
alert(a === a);             // false
var b = 12 + a;              // NaN
var c = 10;
alert(b >= c || b < c);      // false

另一个Number类型中不常引人注目的地方是位运算。JavaScript中提供了按位操作运算符。在很多其他编程语言中,按位操作可以进行硬件级处理,所以非常快。

但是JavaScript没有整数类型,它的位操作是先把数值转换为32位整数,然后进行计算,然后再转换回去,JavaScript绝大部分运行环境是在浏览器中,与硬件相隔较远,因此位操作执行很慢。

3、字符串

与很多其他编程语言中一样,JavaScript中的字符串值也是不可变的,改变一个字符串变量的值,相当于重新生成了一个字符串并把它赋值给变量。JavaScript中的简单类型无法进行方法调用(作为this调用函数),但我们还是可以进行诸如

"abcdefg".toUpperCase();

这样的操作。这是因为JavaScript为简单数据类型提供了一种方式,把它们包装为对象类型,然后进行方法调用。”"abcdefg"“先被隐式地包装为对象,然后使用包装出的对象调用toUpperCase方法,待方法调用结束后,JavaScript再隐式地把包装对象回收。

其它简单数据类型也使用同样的方式。也可以使用JavaScript提供的构造函数显示地创建包装对象,JavaScript提供了String()、Number()和Boolean()三个构造函数,分别用于构建String、Number和Boolean类型的包装对象。

4、类型转换

ECMA-262中对数据类型的转换有详细的定义,很多JavaScript的参考资料也会列出类型转换的详细规则,这里就不再赘述了,下面只讨论一些值得注意的问题。

JavaScript有两组相等比较运算符:”===“和”!==“、”==“和”!=“。Crockford在著作《JavaScript:The Good Parts》里面列举的Bad Parts中的第一个就是”==“运算符。

原因在于”==“运算符会执行隐式的类型转换,而JavaScript中类型转换的规则又非常复杂,很容易导致代码中出现不易发现的bug。与”===“和其他编程语言中的”==“不同,JavaScript中的”==“运算符并不具备传递性: ∀x∀y∀z(x == y ∧ y == z → x == z)并不成立:

"" == "0";             // false
"" == 0;               // true
"0" == 0;              // true

Crockford和Zakas都建议不要使用“==”运算符,而使用“===”代替。若不遵循这个建议,使用“==”运算符时,请务必确保你明确知道两个比较变量的类型信息,以免发生预料之外的类型转换。

另外一个经常用到类型转换的地方是分支判断。if(和其它)语句并不要求进行分支判断的表达式结果必须为Boolean类型,而会根据特定的规则把判断表达式的结果转换为true或false后再进行判断。

if (obj !== undefined && obj !== null) {
    // code
}

// 上面的判断条件可以替换为

if (obj) {
    // code
}

上面代码中的obj代表一个对象变量,若其值为undefined或null,则被转换为false,反之转换为true。这种方式并不完全安全,若使用的变量是简单数据类型,就需要注意一些特殊值的转换规则,否则代码可能不会按照预想的方式执行。

if (typeof num === "number" && num) { 
    // if num is 0, get false
    //code
}

上面代码的本意是获取一个有效的数值类型,屏蔽了其他类型和num的值为NaN的情况(NaN会转换false)。但代码中有一个纰漏,它忽略了num值为0的情况。

0值会被转换为false,从而导致下面的代码不会被执行,这可能与编码者的本意相违背。同样使用String类型作为分支条件,也要考虑""会被自动转换为false的情况。

与分支判断中的类型转换相似的情况,是采用短路方式为变量赋值。由于JavaScript中”&&“和”||“操作符的特性,我们经常采用短路方式为变量赋值。

”&&“操作符会返回表达式中第一个可以转换为false的操作数或最后一个操作数(全为true时);”||“操作符返回表达式中第一个可以转换为true的操作数或最后一个操作数(全为false时)。

var obj = obj1 || obj2 || {}; 
var attr = obj && pro && attr;

与分支判断一样,需要警惕表达式中可能出现的特殊值:0,"",null等。

JavaScript的类型模型,提供了极大的灵活性的同时也带来了很多陷阱,编码过程中需要小心地规避这些陷阱,因为代码审查很容易忽略它们,出现问题时,它们也往往很难被发现。

更多计算机编程相关知识,请访问:编程入门!!

以上是深入了解JS中的原始類型(primitive type)的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述
本文轉載於:OSCHINA。如有侵權,請聯絡admin@php.cn刪除
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庫用於物聯網設備控制,適用於硬件交互。

使用Next.js(後端集成)構建多租戶SaaS應用程序使用Next.js(後端集成)構建多租戶SaaS應用程序Apr 11, 2025 am 08:23 AM

我使用您的日常技術工具構建了功能性的多租戶SaaS應用程序(一個Edtech應用程序),您可以做同樣的事情。 首先,什麼是多租戶SaaS應用程序? 多租戶SaaS應用程序可讓您從唱歌中為多個客戶提供服務

如何使用Next.js(前端集成)構建多租戶SaaS應用程序如何使用Next.js(前端集成)構建多租戶SaaS應用程序Apr 11, 2025 am 08:22 AM

本文展示了與許可證確保的後端的前端集成,並使用Next.js構建功能性Edtech SaaS應用程序。 前端獲取用戶權限以控制UI的可見性並確保API要求遵守角色庫

JavaScript:探索網絡語言的多功能性JavaScript:探索網絡語言的多功能性Apr 11, 2025 am 12:01 AM

JavaScript是現代Web開發的核心語言,因其多樣性和靈活性而廣泛應用。 1)前端開發:通過DOM操作和現代框架(如React、Vue.js、Angular)構建動態網頁和單頁面應用。 2)服務器端開發:Node.js利用非阻塞I/O模型處理高並發和實時應用。 3)移動和桌面應用開發:通過ReactNative和Electron實現跨平台開發,提高開發效率。

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 無盡。

熱門文章

R.E.P.O.能量晶體解釋及其做什麼(黃色晶體)
4 週前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳圖形設置
4 週前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.如果您聽不到任何人,如何修復音頻
4 週前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.聊天命令以及如何使用它們
4 週前By尊渡假赌尊渡假赌尊渡假赌

熱工具

mPDF

mPDF

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

Atom編輯器mac版下載

Atom編輯器mac版下載

最受歡迎的的開源編輯器

EditPlus 中文破解版

EditPlus 中文破解版

體積小,語法高亮,不支援程式碼提示功能

PhpStorm Mac 版本

PhpStorm Mac 版本

最新(2018.2.1 )專業的PHP整合開發工具

WebStorm Mac版

WebStorm Mac版

好用的JavaScript開發工具