亚洲激情专区-91九色丨porny丨老师-久久久久久久女国产乱让韩-国产精品午夜小视频观看

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

JavaScript中的數據類型與變量有哪些

發布時間:2021-08-10 18:03:15 來源:億速云 閱讀:209 作者:Leah 欄目:web開發

JavaScript中的數據類型與變量有哪些,相信很多沒有經驗的人對此束手無策,為此本文總結了問題出現的原因和解決方法,通過這篇文章希望你能解決這個問題。

基本數據類型

在 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_obj ,out_obj 和 in_obj  是兩個引用,它們在內存中的存儲方式是獨立的,但是它們卻指向同一塊內存。

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

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' < 'a' // => 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 < 4; i++) {  setTimeout(function(){  console.log(i);  }, i * 1000);  }

我先不再這里展開分析,我打算放到異步與事件循環機制中去分析。不過這里將 var 替換成 let  可以作為一種解決方案。如果你有興趣,也可以先去分析。

對于 const,這里再補充一點,用于加深對基本類型和引用類型的理解。

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]]  屬性,在后面的文章中分析對象的時候還會提到)

看完上述內容,你們掌握JavaScript中的數據類型與變量有哪些的方法了嗎?如果還想學到更多技能或想了解更多相關內容,歡迎關注億速云行業資訊頻道,感謝各位的閱讀!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

安龙县| 嵩明县| 怀宁县| 乌拉特中旗| 开远市| 高要市| 靖安县| 玉树县| 南川市| 抚松县| 黄陵县| 万年县| 彭阳县| 中山市| 库尔勒市| 连城县| 黄大仙区| 浙江省| 弋阳县| 惠水县| 铜川市| 河东区| 太和县| 四川省| 沙洋县| 义马市| 怀远县| 沙湾县| 建始县| 丹阳市| 寻甸| 万宁市| 逊克县| 青河县| 西峡县| 清徐县| 天柱县| 临泉县| 大理市| 环江| 临武县|