JS相關(guān)概念

JavaScript 定義了幾種數(shù)據(jù)類型? 哪些是原始類型?哪些是復(fù)雜類型?

最新的 ECMAScript 標(biāo)準(zhǔn)定義了 7 種數(shù)據(jù)類型:

原始類型

Number;數(shù)值類型;值:整數(shù)和小數(shù)。
String;字符串類型;值:字符串組成的文本。
Boolean;布爾類型;值:true、false。
Undefined;值:undefined(表示“未定義”或不存在,即由于目前沒有定義)。
Null;值null(表示無(wú)值,即此處的值就是“無(wú)”的狀態(tài))。
Symbol;值:symbol(ECMAScript 6 新定義,表示唯一值)。

復(fù)雜類型
Object;對(duì)象類型;值:各種 “ key:value ” 組成的集合。

區(qū)別

原始類型(基本類型)都是存放著一個(gè)確定的值,它們對(duì)內(nèi)存的占用大小是確定的,存放著棧內(nèi)存中。
復(fù)雜類型存放的內(nèi)容是不確定的,占用的內(nèi)存也是變化的,它的棧內(nèi)存用固定的內(nèi)存存放它在內(nèi)存中的位置,而可變化的內(nèi)容存放著堆內(nèi)存中。
基本類型變量存的是值,復(fù)雜類型的變量存的是內(nèi)存地址。
基本類型在賦值的時(shí)候拷貝值,復(fù)雜類型在賦值的時(shí)候只拷貝地址,不拷貝值。

判斷一個(gè)變量是否是數(shù)字、字符串、布爾、函數(shù)

JavaScript有三種方法,可以確定一個(gè)值到底是什么類型。

typeof運(yùn)算符
instanceof運(yùn)算符
Object.prototype.toString方法(以后再做介紹)

typeof 是用于返回一個(gè)值的數(shù)據(jù)類型,對(duì)于常見的幾大數(shù)據(jù)類型都可以用typeof 數(shù)據(jù)類型的方式進(jìn)行判斷。

一元運(yùn)算符,運(yùn)算格式:
typeof xxx
返回結(jié)果是類型的字符串

數(shù)值、字符串、布爾值分別返回number、string、boolean。
typeof 123;      //number
typeof '123';    //string
typeof false;    //boolean

函數(shù)返回function。
function f() {};
typeof f;          //function
undefined返回undefined。
typeof undefined;   //undefined

除此以外,其他情況都返回object。(局限性)
typeof window;     //object
typeof {};        //object
typeof [];         //object
typeof null;     //object

instanceof 是用于判斷某個(gè)對(duì)象是不是構(gòu)造函數(shù)的一個(gè)實(shí)例,舉例來(lái)說(shuō)就是一個(gè)新聲明的變量是不是調(diào)用了構(gòu)造函數(shù)的內(nèi)置屬性或方法,區(qū)分狹義對(duì)象、數(shù)組、日期、函數(shù)等。

二元運(yùn)算符
instanceof 是一個(gè)二元運(yùn)算符,左邊a是被運(yùn)算的值,右邊b是運(yùn)算的類型。格式如下:
a instanceof b
使用instanceof的都必須是對(duì)象。所以不屬于object類型的基本類型是無(wú)法應(yīng)用instanceof的,或者無(wú)法得到你想要的結(jié)果。
1 instanceof Number
//false
new Number(1) instanceof Number
//true
'string' instanceof String
//false
new String('string') instanceof String
//true
返回結(jié)果是布爾值(Boolean):true/false
所以instanceof是一個(gè)判斷,而typeof是求值
var o = {};
var a = [];
o instanceof Array;     //false
a instanceof Array;     //true

NaN是什么? 有什么特別之處?

NaN 是一種特殊的 Number 類型值。
通常作為沒有得到預(yù)期數(shù)值的返回值,如作為 Math 的某個(gè)方法的返回值出現(xiàn)的(例如:Math.sqrt(-1))或者嘗試將一個(gè)字符串解析成數(shù)字但失敗了的時(shí)候(例如:parseInt("blabla"))
NaN是JavaScript之中唯一不等于自身的值。
typeof NaN   // "number"
NaN !== NaN  // true
 NaN === NaN  // false
任何涉及NaN的數(shù)值操作都會(huì)返回NaN,如NaN+10返回NaN

如何把非數(shù)值轉(zhuǎn)化為數(shù)值?

在JavaScript中,有3個(gè)函數(shù)可以把非數(shù)值轉(zhuǎn)換為數(shù)值,這三個(gè)函數(shù)分別是:Number() 、parselnt() 和 parseFloat()。

第一個(gè)函數(shù),即轉(zhuǎn)型函數(shù) Nurnber() 可以用于任何數(shù)據(jù)類型,而另兩個(gè)函數(shù)則專門用于把字符串轉(zhuǎn)換成數(shù)值。這3個(gè)函數(shù)對(duì)于同樣的輸入會(huì)返回不同的結(jié)果。

Number() 函數(shù)

如果是 Boolean 值,true 和 false 將分別被轉(zhuǎn)換為 1 和0;
如果是數(shù)字值,只是簡(jiǎn)單的傳入和返回;
如來(lái)是null 值,返回 0;
如果是 undefined,返回NaN ;
如果是字符串,遵循下列規(guī)則:
如果字符串中只包含數(shù)字,則將其轉(zhuǎn)換為十進(jìn)制數(shù)值,即"1"會(huì)變成1 , "123"會(huì)變成123,而"011"會(huì)變成11(注意,前導(dǎo)的0被忽略了);
如果字符串中包含有效的浮點(diǎn)格式, 如"1.1",則將其轉(zhuǎn)換為對(duì)應(yīng)的浮點(diǎn)數(shù)值(同樣,也會(huì)忽略前導(dǎo)零);
如果字符串中包含有效的十六進(jìn)制格式,例如"0xf",則將其轉(zhuǎn)換為相同大小的十進(jìn)制整數(shù)值;
如果字符串是空的(包含空字符) ,則將其轉(zhuǎn)換為0;
如果字符串中包含除上述格式之外的字符,則將其轉(zhuǎn)換為 NaN。

如果是對(duì)象,則調(diào)用對(duì)象的 valueOf() 方法,然后依照前面的規(guī)則轉(zhuǎn)換返回的值。如果轉(zhuǎn)換的結(jié)果是 NaN,則調(diào)用對(duì)象的 toString() 方法,然后再次依照前面的規(guī)則轉(zhuǎn)換返回的字符串值。
var num1 = Number("Hello world!");  // NaN
var num2 = Number("   ");  // 0
var num3 = Numberl("000011");  // 11
var num4 = Number(true);  // 1

parseInt() 函數(shù)

由于 Number() 函數(shù)在轉(zhuǎn)換字符串時(shí)比較復(fù)雜而且不夠合理,因此在處理整數(shù)的時(shí)候更常用的是 parseInt() 函數(shù)。
parselnt() 函數(shù)在轉(zhuǎn)換字符串時(shí),更多的是看其是否符合數(shù)值模式,它會(huì)忽略字符串前面的空格,直至找到第一個(gè)非空格字符;如果第一個(gè)字符不是數(shù)字字符或者負(fù)號(hào),parseInt() 就會(huì)返回 NaN;也就是說(shuō),用parselnt() 轉(zhuǎn)換空字符時(shí)會(huì)返回 NaN(Nurnber() 對(duì)空字符返回 0); 如果第一個(gè)字符是數(shù)字字符,parselnt() 會(huì)繼續(xù)解析第二個(gè)字符,直到解析完所有后續(xù)字符或者遇到了一個(gè)非數(shù)字字符。例如,"1234blue"會(huì)被轉(zhuǎn)換為1234 ,因?yàn)?blue"會(huì)被完全忽略;類似地,"'22.5"會(huì)被轉(zhuǎn)換為22 ,因?yàn)樾?shù)點(diǎn)并不是有效的數(shù)字字符。
如果字符串中的第一個(gè)字符是數(shù)字字符,parselnt() 也能夠識(shí)別出各種整數(shù)格式(即前面討論的十進(jìn)制、八進(jìn)制和十六進(jìn)制數(shù)) 。也就是說(shuō),如果字符以"0x"開頭且后跟數(shù)字字符,就會(huì)將其當(dāng)作一個(gè)十六進(jìn)制整數(shù);如果字符串以"0"開頭且后跟數(shù)字字符,則會(huì)將其當(dāng)作一個(gè)八迸制數(shù)來(lái)解析。
ES5不再允許將帶有前綴0的數(shù)字視為八進(jìn)制數(shù),而是要求忽略這個(gè)0。但是,為了保證兼容性,大部分瀏覽器并沒有部署這一條規(guī)定。
var num1 = parselnt ("1234blue") ;  // 1234
var num2 = parselnt (" ") ;   // NaN
var num3 = parselnt ("0xA") ;  // 10(十六進(jìn)制數(shù))
var num4 = parseInt(22.5);   // 22
var num5 = parselnt ("070") ;  // 56(八進(jìn)制數(shù))
var num6 = parselnt("70");  //70(十進(jìn)制數(shù))
var num7 = parselnt ("0xf") ;  // 15(十六進(jìn)制數(shù))
如果知道被解析的是十六進(jìn)制格式的字符串,那么指定基數(shù)16 作為第二個(gè)參數(shù),可以保證得到正確的結(jié)果,例如:
var num = parselnt("0xAF", 16);   //175
實(shí)際上,如果指定了16 作為第二個(gè)參數(shù),字符串可以不帶前面的"0x",如下所示:
var num1 = parseInt( 'AF' , 16);   //175
var num2 = parselnt ("AF") ;   // NaN
指定基數(shù)會(huì)影響到轉(zhuǎn)換的輸出結(jié)果。例如:
var num1 = parselnt ("10", 2);  // 2(按照二進(jìn)制解析)
var num2 = parseInt("10", 8);  // 8(按照八進(jìn)制解析)
var num3 = parselnt("10", 10);  // 10(按照十進(jìn)制解析)
var num4 = parselnt("10", 16);  // 16(按照十六進(jìn)制解析)

parseFloat() 函數(shù)

與 parseInt () 函數(shù)類似,parseFloat () 也是從第一個(gè)字符(位置0)開始解析每個(gè)字符。而且也是一直解析到字符串末尾,或者解析到遇見一個(gè)無(wú)效的浮點(diǎn)數(shù)字字符為止。也就是說(shuō),字符串中的第一個(gè)小數(shù)點(diǎn)是有效的,而第二個(gè)小數(shù)點(diǎn)就是無(wú)效的了,因此它后面的字符串將被忽略。舉例來(lái)說(shuō),"22.34.5"將會(huì)被轉(zhuǎn)換為22.34 。
除了第一個(gè)小數(shù)點(diǎn)有效之外, parseFloat () 與 parselnt() 的第二個(gè)區(qū)別在于它始終都會(huì)忽略前導(dǎo)的零。parseFloat() 可以識(shí)別前面討論過(guò)的所有浮點(diǎn)數(shù)值格式,也包括十迸制整數(shù)格式,但十六進(jìn)制格式的字符串則始終會(huì)被轉(zhuǎn)換成0。由于 parseFloat() 只解析十進(jìn)制值,因此它沒有用第二個(gè)參數(shù)指定基數(shù)的用法。最后還要注意一點(diǎn):如果字符串包含的是一個(gè)可解析為整數(shù)的數(shù)(沒有小數(shù)點(diǎn),或者小數(shù)點(diǎn)后都是零),parseFloat() 會(huì)返回整數(shù)。以下是使用 parseFloat() 轉(zhuǎn)換數(shù)值的幾個(gè)典型示例:
var num1 = parseFloat ("1234blue") ;  // 1234(整數(shù))
var num2 = parseFloat("0xA");   // 0
var num3 = parseFloat("22.5");  // 22.5
var num4 = parseFloat("22.34.5");  // 22.5
var num5 = parseFloat("0908.5");   // 908
var num6 = parseFloat("3.125e7");   // 31250000

==與===有什么區(qū)別?

x == y 在對(duì)比 x 和 y 的值之前,會(huì)嘗試對(duì) x 和 y 做類型轉(zhuǎn)換,變成同一種類型后,再對(duì)比。
x===y會(huì)對(duì)比x和y是否同類型,不同類型會(huì)返回false,不會(huì)發(fā)生轉(zhuǎn)換。
== 會(huì)做類型轉(zhuǎn)換,=== 不做類型轉(zhuǎn)化

break與continue有什么區(qū)別

二者都是為了控制代碼循環(huán)執(zhí)行,執(zhí)行到之后都會(huì)立即跳出循環(huán)
break退出循環(huán)后,會(huì)繼續(xù)執(zhí)行后續(xù)的語(yǔ)句
for(var i=0;i<3;i++){
  for(var j=0;j<3;j++){
    console.log(j)
    break
  }
  console.log('我')
}
//0
//'我'
//0
//'我'
//0
//'我'
continue退出循環(huán)后,會(huì)再?gòu)淖钔鈱友h(huán)開始執(zhí)行(注意外層循環(huán)次數(shù)沒有累加)
for(var i=0;i<2;i++){
  for(var j=0;j<3;j++){
    console.log(j)
    continue
  }
  console.log('我')
}
//0
//1
//2
//"我"
//0
//1
//2
//"我"

void 0 和 undefined在使用場(chǎng)景上有什么區(qū)別

undefined 全局作用域下不能被重寫,但是在局部作用域中,可以被重寫的。所以u(píng)ndefined現(xiàn)常用于全局環(huán)境。
void 運(yùn)算符通常只用于獲取 undefined 的原始值,一般使用 void(0)(等同于 void 0)。在上述情況中,也可以使用全局變量undefined 來(lái)代替(假定其仍是默認(rèn)值)。
而 void 可以給任何給定的表達(dá)式求值,并返回 undefined,并且 void 不可被重寫,因此void 0是在局部作用域中替代undefined的最佳選擇 。

以下代碼的輸出結(jié)果及原因

console.log(1+1);
console.log(1+1);      // 2
"+" 兩邊都是數(shù)值類型,做數(shù)值運(yùn)算。
console.log("2"+"4");
console.log("2"+"4");    //24
"+" 兩邊都是字符串類型,直接拼接。
console.log(2+"4");
console.log(2+"4");    //24
"+" 一邊是數(shù)值類型,另一邊是字符串類型,數(shù)值類型轉(zhuǎn)為字符串類型后拼接。
console.log(+"4");
console.log(+"4");    //4
"+" 只有右側(cè)一個(gè)操作數(shù),轉(zhuǎn)換我數(shù)值類型。

以下代碼的輸出結(jié)果及原因

var a = 1;
a+++a;
typeof a+2;
var a = 1;       
console.log(a+++a);     //3
console.log(typeof a+2);     //number2
因?yàn)?…++"優(yōu)先級(jí)高于"+"優(yōu)先級(jí)高于"++…","a+++a" 相當(dāng)于"(a++)+a",即"1+2"返回 3 ;
"typeof a+2"相當(dāng)于"(typeof a)+2",即"number+2",做字符串拼接返回number2。

以下代碼的輸出結(jié)果及原因

 var a = 1;
 var b = 3;
 console.log( a+++b );   //4
因?yàn)?…++"優(yōu)先級(jí)高于"+"優(yōu)先級(jí)高于"++…","a+++b" 相當(dāng)于"(a++)+b",即"1+3"返回 4;

遍歷數(shù)組,把數(shù)組里的打印數(shù)組每一項(xiàng)的平方

 var arr=[3,4,5]
for(var i in arr){
  console.log(arr[i]*arr[i])
}
//9
//16
//25

遍歷 JSON, 打印里面的值

var obj = {
 name: 'hunger', 
 sex: 'male', 
 age: 28 
}
for(var key in obj){
  console.log(key+':'+obj[key])
}
//"name:hunger"
//"sex:male"
//"age:28"

以下代碼輸出結(jié)果及原因

var a = 1, b = 2, c = 3;
var val = typeof a + b || c >0
console.log(val) 
//"number2"
優(yōu)先級(jí):typeof>"+">"||",所以相當(dāng)于"number2" || c>0,返回"number2"。
var d = 5;
var data = d ==5 && console.log('bb')
console.log(data)
//"bb"
//undefined
優(yōu)先級(jí):"==">"+"&&",所以相當(dāng)于true && undefined,返回undefined。
var data2 = d = 0 || console.log('haha')
console.log(data2)
//"haha"
//undefined
相當(dāng)于data2=d=0|| undefined,0布爾值為false,所以返回undefined。
var x = !!"Hello" + (!"world", !!"from here!!");
console.log(x)
//2
優(yōu)先級(jí):"=">"!">"+",相當(dāng)于var x=true + (false,true),加號(hào)優(yōu)先將操作數(shù)轉(zhuǎn)為數(shù)字,所以得到2。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 第5章 引用類型(返回首頁(yè)) 本章內(nèi)容 使用對(duì)象 創(chuàng)建并操作數(shù)組 理解基本的JavaScript類型 使用基本類型...
    大學(xué)一百閱讀 3,691評(píng)論 0 4
  • “44年前我們就把人類送上月球了,但現(xiàn)在我們?nèi)匀粺o(wú)法在CSS中實(shí)現(xiàn)垂直居中”James An derson 使用如...
    zhangmz閱讀 969評(píng)論 0 50
  • 茶和咖啡是我最喜歡的飲品。 中國(guó)的飲茶文化據(jù)說(shuō)始于神農(nóng)時(shí)代。我對(duì)茶文化沒什么研究,喜歡喝家鄉(xiāng)綠茶是一種習(xí)慣,直到有...
    一清一秋閱讀 631評(píng)論 0 0
  • 我允許自己深陷在無(wú)邊的悲傷之中,找不到岸。 最初的低落來(lái)自哪里呢?也許是午飯前的那場(chǎng)開卷考試。題目不會(huì)做,但又是第...
    我家洗硯池邊樹閱讀 350評(píng)論 1 0

友情鏈接更多精彩內(nèi)容