搜尋
首頁web前端js教程JavaScript的資料型態與變數的解析(附範例)

這篇文章帶給大家的內容是關於JavaScript的資料型別與變數的解析(附範例),有一定的參考價值,有需要的朋友可以參考一下,希望對你有幫助。

這篇文章,來聊聊 JS 中的資料型別與變數。這是在學習 JS 時最基礎的一類問題,但卻很重要。希望我的分享有幫助到你。

文章開頭,我先提幾個面試中遇到的問題:

例如:

#如何理解參數的按值傳遞?

什麼是暫時性死區?

什麼是變數提升?

全域變數和 window 的屬性有什麼差別?為什麼?

... ...

這篇文章的風格,在分析知識點的同時,插入一些我經歷過的面試題目。

基本資料型態

在 JS 中,基本資料型別有 6 種,分別是數值、字串、布林值、null、undefined、Symbol。

對於基本資料類型,我們需要明白的是:基本類型在記憶體中的儲存方式是堆疊。每一個數值都是單獨存放,互不影響。

基本類型都是按值存取的。在比較時,按值進行比較:

1 === 1 // true

引用資料類型

引用類型的值保存在堆疊中,而引用是保存在堆疊中。

引用類型按引用存取。在比較時,也比較的參考:

{} === {} // => false

參數的傳遞方式

在 JS 中,參數可以是任何類型的值,甚至可以是函數。

這裡要分析的是參數是以哪一種型別傳遞的?引用型別還是基本型別?

先看一個基礎的例子:

var out_num = 1;

function addOne(in_num) {
    in_num += 1;
    return in_num;
}

addOne(out_num); // => 2
out_num // => 1

這個例子中,我們給addOne() 函數傳遞一個實參out_num,這個時out_num 會傳遞給in_num,即內部存在著in_num = out_num 的過程。最後我們看到的結果是 out_num 並沒有被函數改變,說明 in_num 和 out_num 是兩個在記憶體中獨立存放的值,也就是按值傳遞。

再來看一個變形:

var out_obj = { value: 1 };

function addOne(in_obj) {
    in_obj.value += 1;
    return in_obj;
}

addOne(out_obj); // => { value: 2 }
out_obj // => { value: 2 }

問題來了?函數參數不是按值傳遞嗎?為什麼這裡函數內部的處理反映到外部了? 這是一個超級超級超級的理解迷思。

首先,我們還是得擺正觀點,也就是函數參數是按值傳遞的。 那這裡怎麼理解呢?對於引用型別而言,前面說引用型別分為引用和實際的記憶體空間。這裡 out_obj 依舊傳遞給 in_obj,即 in_obj = out_objout_obj 和 in_obj 是兩個引用,它們在記憶體中的儲存方式是獨立的,但是它們卻指向同一塊記憶體。

in_obj.value = 1 則是直接操作的實際物件。實際物件的改變,會同步到所有引用這個實際物件的引用。

JavaScript的資料型態與變數的解析(附範例)

JavaScript的資料型態與變數的解析(附範例)

你再來看這個例子,或許會更清楚一些。

var out_obj = { value: 1 };

function addOne(in_obj) {
    in_obj = { value: 2 };
    return in_obj;
}

addOne(out_obj); // => { value: 2 }
out_obj // => { value: 1 }

你只要抓住一點:物件的賦值就會造成引用指向的實際物件改變。

如何判斷資料型別

判斷資料型別,通常有三種具體的方法:

1、typeof 運算子

typeof 操作符傳回一個表示資料類型的字串。它有以下明顯的缺陷:

typeof null // => 'object'

typeof [] // => 'object'

這是因為在 JS 語言設計之初遺留的 bug。可以閱讀這篇文章 http://2ality.com/2013/10/typ... 了解更多關於 typeof 處理 null 的問題。

所以 typeof 最好用來判斷一些基本類型,像是數值、字串、布林值、undefined、Symbol。

2、instanceof 運算子

typeof  的背後是透過判斷type tags 來判斷資料類型,而instanceof 則是透過判斷建構函數的prototype 是否出現在物件原型鏈上的任何位置。

舉例:

{} instanceof Object // => true

[] instanceof Array // => true
[] instanceof Object // => true

也判斷自訂類型:

function Car(make, model, year) {
  this.make = make;
  this.model = model;
  this.year = year;
}
var auto = new Car('Honda', 'Accord', 1998);

console.log(auto instanceof Car);
// => true

console.log(auto instanceof Object);
// => true

所以,對於字面量形式的基本資料類型,不能透過instanceof 來判斷:

1 instanceof Number // => false

Number(1) instanceof Number // => false

new Number(1) instanceof Number // => true

3、Object.prototype.toString()

這是目前最推薦的一種方法,可以更精細且準確的判斷任何資料類型,甚至是JSON、正規、日期、錯誤等等。在 Lodash 中,其判斷資料型別的核心也是 Object.prototype.toString() 方法。

Object.prototype.toString.call(JSON) // => "[object JSON]"

關於這背後的原理,你可以閱讀這篇文章http://www.cnblogs.com/ziyunf...

4、其他

上面三種是通用的判斷資料類型的方法。面試中也會出現如何判斷一個陣列、如何判斷 NaN、如何判斷類別陣列物件、如何判斷一個空物件等問題。這一類問題比較開放,解決想法通常是抓住判斷資料的核心特徵。

舉個例子:判斷類別數組物件。

你先要知道 JS 中类数组对象是什么样子的,并寻求一个实际的参照物,比如 arguments 就是类数组对象。那么类数组对象具有的特点是:真值 & 对象 & 具有 length 属性 & length 为整数 & length 的范围大于等于 0,小于等于最大安全正整数(Number.MAX_SAFE_INTEGER)。

在你分析特点的时候,答案就呼之欲出了。【注意全面性】

数据类型如何转换

JS 数据类型的动态性将贯穿整个 JS 的学习,这是 JS 非常重要的特性,很多现象就是因为动态性的存在而成为 JS 独有。

正是由于动态性,JS 的数据类型可能在你毫无察觉的情况下,就发生了改变,直到运行时报错。

这里主要分析下面 8 种转换规则。

1、if 语句

if 语句中的类型转换是最常见的。

if (isTrue) {
    // ...
} else {}

在 if 语句中,会自动调用 Boolean() 转型函数对变量 isTrue 进行转换。

当 isTrue 的值是 null, undefined, 0, NaN, '' 时,都会转为 false。其余值除 false 本身外都会转为 true。

2、Number() 转型函数

我们重点关注 null undefined 以及字符串在 Number() 下的转换:

Number(null) // => 0
Number(undefined) // => NaN
Number('') // => 0
Number('123') // => 123
Number('123abc') // => NaN

注意和 parseInt() 对比。

3、parseInt()

parseInt(null) // => NaN
parseInt(undefined) // => NaN
parseInt('') // => NaN
parseInt('123') // => 123
parseInt('123abc') // => 123

4、==

这里需要注意的是:

null == undefined // => true

null == 0 // => false
undefined == false // => false

null 与 undefined 的相等性是由 ECMA-262 规定的,并且 null 与 undefined 在比较相等性时不能转换为其他任何值。

5、关系操作符

对于两个字符串的比较,是比较的字符编码值:

'B'  true

一个数值,另一个其他类型,都将转为数字进行比较。

两个布尔值转为数值进行比较。

对象,先调用 valueOf(),若不存在该方法,则调用 toString()。

6、加法

加法中特别注意的是,数字和字符串相加,将数字转为字符串。

'1' + 2 => // '12'
1 + 2 => // 3

对于对象和布尔值,调用它们的 toString() 方法得到对应的字符串值,然后进行字符串相加。对于 undefined 和 null 调用 String() 取得字符串 'undeifned' 和 'null'。

{ value: 1 } + true // => "[object Object]true"

7、减法

对于字符串、布尔值、null 或者 undefined,自动调用 Number(),转换结果若为 NaN,那么最终结果为 NaN。

对于对象,先调用 valueOf(),如果得到 NaN,结果为 NaN。如果没有 valueOf(),则调用 toString()。

8、乘法、除法

对于非数值,都会调用 Number() 转型函数。

变量提升与暂时性死区

JS 中有三种声明变量的方式:var, let, const。

var 声明变量最大的一个特点是存在变量提升。

console.log(a); // undefined
var a = 1;
console.log(a); // 1

第一个打印结果表示,在声明变量 a 之前,a 就已经可以访问了,只不过并未赋值。这就是变量提升现象。(具体原因,我放在后面分析作用域的时候来写)

let 和 const 就不存在这个问题,但是又引入了暂时性死区这样的概念。

/**
* 这上面都属于变量 a 的暂时性死区
* console.log(a) // => Reference Error
*/
let a = 1;
console.log(a); // => 1

即声明 a 之前,不能够访问 a,而直接报错。

而暂时性死区的出现又引出另外一个问题,即 typeof 不再安全。你可以参考这篇文章 http://es-discourse.com/t/why...

补充:一个经典面试题

for (var i = 0; i <p>我先不再这里展开分析,我打算放到异步与事件循环机制中去分析。不过这里将 var 替换成 let 可以作为一种解决方案。如果你有兴趣,也可以先去分析。</p><p>对于 const,这里再补充一点,用于加深对基本类型和引用类型的理解。</p><pre class="brush:php;toolbar:false">const a = 1;
const b = { value: 1 };

a = 2; // => Error
b.value = 2; // => 2
b = { value: 2 }; // => Error

本质上,const 并不是保证变量的值不得改动,而是变量指向的内存地址不得改动。

声明全局变量

直接通过 var 声明全局变量,这个全局变量会作为 window 对象的一个属性。

var a = 1;
window.a // => 1

在这里提出两个问题,一是 let 声明的全局变量会成为 window 的属性吗?二是 var 声明的全局变量和直接在 window 创建属性有没有区别?

先来回答第一问题。let 声明的全局变量不会成为 window 的属性。用什么来支撑这样的结论呢?在 ES6 中,对于 let 和 const 声明的变量从一开始就形成封闭作用域。想想之前的暂时性死区。

第二个问题,var 声明的全局变量和直接在 window 创建属性存在着本质的区别。先看下面的代码:

var a = 1;
window.a // => 1

window.b = 2;

delete window.a
delete window.b

window.a // => 1
window.b // => undefined

我们可以看到,直接创建在 window 上的属性可以被 delete 删除,而 var 创建的全局属性则不会。这是现象,通过现象看本质,二者本质上的区别在于:

使用 var 宣告的全域變數的 [[configurable]] 資料屬性的值為 false,不能透過 delete 刪除。而直接在物件上建立的屬性預設 [[configurable]] 的值為 true,即可以被 delete 刪除。 (關於[[configurable]] 屬性,在後面的文章中分析物件的時候還會提到)

小結

在這篇「資料類型與變量」文章中,分析了7 個大類。再來回顧一下:

基本型別、參考型別、參數傳遞方式、如何判斷資料型別、資料型別轉換、變數提升與暫時性死區、宣告全域變數。

這些不僅是校招面試中的高頻考點,也是學習 JS 必不可少的知識點。

Tip1:《JavaScript 高階程式設計》這本書被稱為「前端的聖經」是有原因的。對於正在準備校園招募的你,非常有必要! 書讀百遍,其義自見。 你會發現你在面試中遇到的絕大部分 JS 相關的知識點都能在這本書中找到「答案」!

Tip2:在準備複習的過程中,注意知識的模組性與相關性。你得有自己劃分知識模組的能力,例如今天的「資料類型與變數」模組。相關性是指,任何的知識都是由連結的,例如這裡牽涉到作用域、記憶體等模組。

#

以上是JavaScript的資料型態與變數的解析(附範例)的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述
本文轉載於:segmentfault。如有侵權,請聯絡admin@php.cn刪除
Python vs. JavaScript:開發人員的比較分析Python vs. JavaScript:開發人員的比較分析May 09, 2025 am 12:22 AM

Python和JavaScript的主要區別在於類型系統和應用場景。 1.Python使用動態類型,適合科學計算和數據分析。 2.JavaScript採用弱類型,廣泛用於前端和全棧開發。兩者在異步編程和性能優化上各有優勢,選擇時應根據項目需求決定。

Python vs. JavaScript:選擇合適的工具Python vs. JavaScript:選擇合適的工具May 08, 2025 am 12:10 AM

選擇Python還是JavaScript取決於項目類型:1)數據科學和自動化任務選擇Python;2)前端和全棧開發選擇JavaScript。 Python因其在數據處理和自動化方面的強大庫而備受青睞,而JavaScript則因其在網頁交互和全棧開發中的優勢而不可或缺。

Python和JavaScript:了解每個的優勢Python和JavaScript:了解每個的優勢May 06, 2025 am 12:15 AM

Python和JavaScript各有優勢,選擇取決於項目需求和個人偏好。 1.Python易學,語法簡潔,適用於數據科學和後端開發,但執行速度較慢。 2.JavaScript在前端開發中無處不在,異步編程能力強,Node.js使其適用於全棧開發,但語法可能複雜且易出錯。

JavaScript的核心:它是在C還是C上構建的?JavaScript的核心:它是在C還是C上構建的?May 05, 2025 am 12:07 AM

javascriptisnotbuiltoncorc; sanInterpretedlanguagethatrunsonenginesoftenwritteninc.1)JavascriptwasdesignedAsignedAsalightWeight,drackendedlanguageforwebbrowsers.2)Enginesevolvedfromsimpleterterpretpretpretpretpreterterpretpretpretpretpretpretpretpretpretcompilerers,典型地,替代品。

JavaScript應用程序:從前端到後端JavaScript應用程序:從前端到後端May 04, 2025 am 12:12 AM

JavaScript可用於前端和後端開發。前端通過DOM操作增強用戶體驗,後端通過Node.js處理服務器任務。 1.前端示例:改變網頁文本內容。 2.後端示例:創建Node.js服務器。

Python vs. JavaScript:您應該學到哪種語言?Python vs. JavaScript:您應該學到哪種語言?May 03, 2025 am 12:10 AM

選擇Python還是JavaScript應基於職業發展、學習曲線和生態系統:1)職業發展:Python適合數據科學和後端開發,JavaScript適合前端和全棧開發。 2)學習曲線:Python語法簡潔,適合初學者;JavaScript語法靈活。 3)生態系統:Python有豐富的科學計算庫,JavaScript有強大的前端框架。

JavaScript框架:為現代網絡開發提供動力JavaScript框架:為現代網絡開發提供動力May 02, 2025 am 12:04 AM

JavaScript框架的強大之處在於簡化開發、提升用戶體驗和應用性能。選擇框架時應考慮:1.項目規模和復雜度,2.團隊經驗,3.生態系統和社區支持。

JavaScript,C和瀏覽器之間的關係JavaScript,C和瀏覽器之間的關係May 01, 2025 am 12:06 AM

引言我知道你可能會覺得奇怪,JavaScript、C 和瀏覽器之間到底有什麼關係?它們之間看似毫無關聯,但實際上,它們在現代網絡開發中扮演著非常重要的角色。今天我們就來深入探討一下這三者之間的緊密聯繫。通過這篇文章,你將了解到JavaScript如何在瀏覽器中運行,C 在瀏覽器引擎中的作用,以及它們如何共同推動網頁的渲染和交互。 JavaScript與瀏覽器的關係我們都知道,JavaScript是前端開發的核心語言,它直接在瀏覽器中運行,讓網頁變得生動有趣。你是否曾經想過,為什麼JavaScr

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脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

SecLists

SecLists

SecLists是最終安全測試人員的伙伴。它是一個包含各種類型清單的集合,這些清單在安全評估過程中經常使用,而且都在一個地方。 SecLists透過方便地提供安全測試人員可能需要的所有列表,幫助提高安全測試的效率和生產力。清單類型包括使用者名稱、密碼、URL、模糊測試有效載荷、敏感資料模式、Web shell等等。測試人員只需將此儲存庫拉到新的測試機上,他就可以存取所需的每種類型的清單。

SublimeText3 英文版

SublimeText3 英文版

推薦:為Win版本,支援程式碼提示!

Safe Exam Browser

Safe Exam Browser

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

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

Atom編輯器mac版下載

Atom編輯器mac版下載

最受歡迎的的開源編輯器