1.JavaScript 定義了幾種數(shù)據(jù)類型? 哪些是原始類型?哪些是復(fù)雜類型?原始類型和復(fù)雜類型的區(qū)別是什么?
JavaScript 定義了7種數(shù)據(jù)類型
-
6種原始類型
- boolean :true(真)和false(假)兩個(gè)特定值
- null :表示空缺,即此處應(yīng)該有一個(gè)值,但目前為空
- undefined :表示“未定義”或不存在,即此處目前沒有任何值
- string :字符組成的文本(比如"Hello World")
- number: 整數(shù)和小數(shù)(比如1和3.14)
- symbol(ECMAScript 6 新定義)
-
object類型即復(fù)雜類型(eg:Object,Array,Function,Data)
區(qū)別:
一、原始類型(基本類型)
- 基本數(shù)據(jù)類型的值是不可變的
var name = "change";
name.substr();//hang
console.log(name);//change - 基本數(shù)據(jù)類型不可以添加屬性和方法
var p = "change";
p.age = 29;
p.method = function(){console.log(name)};
console.log(p.age)//undefined
console.log(p.method)//undefined - 基本數(shù)據(jù)類型的賦值是簡(jiǎn)單賦值
如果從一個(gè)變量向另一個(gè)變量賦值基本類型的值,會(huì)在變量對(duì)象上創(chuàng)建一個(gè)新值,然后把該值復(fù)制到為新變量分配的位置上
var a = 10;
var b = a;
a++;
console.log(a)//11
console.log(b)//10 - 基本數(shù)據(jù)類型的比較是值的比較
var person1 = '{}';
var person2 = '{}';
console.log(person1 == person2); // true -
基本數(shù)據(jù)類型是存放在棧區(qū)的
var name = "jozo";var city = "guangzhou";var age = 22;
那么它的存儲(chǔ)結(jié)構(gòu)如下圖:
二、復(fù)雜類型(引用類型)
1. 引用類型的值是可以改變的
var a = [1,2,3];
a[0] = 0;//更改數(shù)組的一個(gè)元素
a[3] = 4;//給數(shù)組增加一個(gè)元素
- 引用類型可以添加屬性和方法
var person = {};
person.name = "change";
person.say = function(){alert("hello");}
console.log(person.name)//change
console.log(person.say)//function(){alert("hello");} -
引用類型的賦值是對(duì)象引用
var a = {};
var b= a;
a.name = "change";
console.log(a.name)//change;
console.log(b.name)//change
b.age = 29;
console.log(a.age)//29
console.log(b.age)//29
引用類型保存在變量中的是對(duì)象在堆內(nèi)存中的地址,所以,與基本數(shù)據(jù)類型的簡(jiǎn)單賦值不同,這個(gè)值的副本實(shí)際上是一個(gè)指針,而這個(gè)指針指向存儲(chǔ)在堆內(nèi)存的一個(gè)對(duì)象.那么賦值操作后,兩個(gè)變量都保存了同一個(gè)對(duì)象地址,而這兩個(gè)地址指向了同一個(gè)對(duì)象.因此,改變其中任何一個(gè)變量,都會(huì)互相影響
-
引用類型的比較是引用的比較
var person1 = {};
var person2 = {};
console.log(person1 == person2)//false
因?yàn)橐妙愋偷谋容^是引用的比較,換句話說,就是比較兩個(gè)對(duì)象保存在棧區(qū)的指向堆內(nèi)存的地址是否相同,此時(shí),雖然p1和p2看起來都是一個(gè)"{}",但是他們保存在棧區(qū)中的指向堆內(nèi)存的地址卻是不同的,所以兩個(gè)對(duì)象不相等
-
引用類型是同時(shí)保存在棧區(qū)和堆區(qū)中的
var person1 = {name:"change1"};
var person2 = {name:"change2"};
var person3 = {name:"change3"};
則這三個(gè)對(duì)象在內(nèi)存中保存的情況如下圖:
2.typeof和instanceof的作用和區(qū)別?
1.typeof操作符是確定一個(gè)變量是字符串、數(shù)值、布爾、還是undefined的最佳工具,但在檢測(cè)引用類型的值時(shí),這個(gè)操作符的用處不大。
類型 | 結(jié)果 |
---|---|
Undefined | "undefined" |
Null | "object" |
Boolean | "boolean" |
Number | "number" |
String | "string" |
任何其他對(duì)象 | "object" |
2.instanceof運(yùn)算符用來測(cè)試一個(gè)對(duì)象在其原型鏈中是否存在一個(gè)構(gòu)造函數(shù)的 prototype 屬性,即用來知道是什么類型的對(duì)象。
person instanceof Object //person是Object嗎
function C(){}
function D(){}
var o = new C(); o instanceof C;// true,因?yàn)?Object.getPrototypeOf(o) === C.prototype var a=[]; a instanceof Array;//true
3.如何判斷一個(gè)變量是否是數(shù)字、字符串、布爾、函數(shù)
使用typeof判斷
4.NaN是什么? 有什么特別之處?
NaN是JavaScript的特殊值,表示“非數(shù)字”(Not a Number)
特點(diǎn):
1.NaN不是數(shù)字,但是它的數(shù)據(jù)類型是數(shù)字
typeof NaN; //number
2.NaN是JavaScript之中唯一不等于自身的值,不等于任何值,包括它本身
NaN == NaN; //false NaN === NaN; //false
3.NaN在布爾運(yùn)算時(shí)被當(dāng)作false
Boolean(NaN); //false
4.NaN與任何數(shù)(包括它自己)的運(yùn)算,得到的都是NaN
NaN + 32 //NaN NaN - 32 //NaN NaN * 32 //NaN NaN / 32 //NaN
5.判斷NaN的方法
isNaN()原理:isNaN()會(huì)將括號(hào)內(nèi)的參數(shù)利用Number()進(jìn)行一次轉(zhuǎn)換.
由于會(huì)對(duì)參數(shù)用Number()進(jìn)行一次數(shù)據(jù)轉(zhuǎn)換,故對(duì)于字符串、部分對(duì)象、部分?jǐn)?shù)組、undefined等,isNaN()會(huì)返回true
isNaN('NaN'); //true 等同于isNaN(Number('NaN')); isNaN({}); //true 等同于isNaN(Number({})); isNaN(['xzy']); //true 等同于isNaN(Number(['xzy'])); isNaN(undefined); //true 等同于isNaN(Number(undefined)); Number(undefined)的結(jié)果為NaN
但是,對(duì)于空數(shù)組、只有一個(gè)數(shù)值成員的數(shù)組、null等,isNaN()返回false
isNaN([]); //false isNaN([123]); //false isNaN(['123']); //false isNaN(null); //false Number(null)的結(jié)果為0
5.如何把非數(shù)值轉(zhuǎn)化為數(shù)值?
javascript有3個(gè)函數(shù)可以把非數(shù)值轉(zhuǎn)換為數(shù)值:Number()、parseInt()、parseFloat()。
Number()可以用于任何數(shù)據(jù)類型(此函數(shù)平時(shí)很少使用)。
parseInt()、parseFloat()專門用于把字符串轉(zhuǎn)換成數(shù)值(比較常用的)。
- parseInt(string, radix):識(shí)別整數(shù)格式。
如果字符串中的第一個(gè)字符是數(shù)字字符,parselnt() 也能夠識(shí)別出各種整數(shù)格式(即前面討論的十進(jìn)制、八進(jìn)制和十六進(jìn)制數(shù)) 。也就是說,如果字符以"0x"開頭且后跟數(shù)字字符,就會(huì)將其當(dāng)作一個(gè)十六進(jìn)制整數(shù);如果字符串以"0"開頭且后跟數(shù)字字符,則會(huì)將其當(dāng)作一個(gè)八迸制數(shù)來解析。
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ù))
- parseFloat() :識(shí)別浮點(diǎn),且第一個(gè)浮點(diǎn)有效
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
- Number()轉(zhuǎn)換規(guī)則:
1.如果是 Boolean 值,true 和 false 將分別被轉(zhuǎn)換為 1 和0;Number(true) //1
2.如果是數(shù)字值,只是簡(jiǎn)單的傳入和返回;
Number(12) //12
3.如來是null 值,返回 0;
Number(null) //0
4.如果是 undefined,返回NaN ;
Number(undefined)//NaN
5.如果是字符串,遵循下列規(guī)則:
a.如果字符串中只包含數(shù)字,則將其轉(zhuǎn)換為十進(jìn)制數(shù)值,即"1"會(huì)變成1 , "123"會(huì)變成123,而"011"會(huì)變成11(注意,前導(dǎo)的0被忽略了);
b.如果字符串中包含有效的浮點(diǎn)格式, 如"1.1",則將其轉(zhuǎn)換為對(duì)應(yīng)的c.浮點(diǎn)數(shù)值(同樣,也會(huì)忽略前導(dǎo)零);
d.如果字符串中包含有效的十六進(jìn)制格式,例如"0xf",則將其轉(zhuǎn)換為相同大小的十進(jìn)制整數(shù)值;
Number(0xf)//15
e如果字符串是空的(不包含任何字符) ,則將其轉(zhuǎn)換為0;
Number("")//0
f.如果字符串中包含除上述格式之外的字符,則將其轉(zhuǎn)換為 NaN。
g.如果是對(duì)象,則調(diào)用對(duì)象的 valueOf() 方法,然后依照前面的規(guī)則轉(zhuǎn)換返回的值。如果轉(zhuǎn)換的結(jié)果是 NaN,則調(diào)用對(duì)象的 toString() 方法,然后再次依照前面的規(guī)則轉(zhuǎn)換返回的字符串值
6.==與===有什么區(qū)別
==:等于運(yùn)算(值的比較),但是不比較值的類型, 兩邊值類型不同的時(shí)候,要先進(jìn)行類型轉(zhuǎn)換,再比較。
===:完全等于運(yùn)算(值和類型的比較),不僅比較值,而且還比較值的類型,當(dāng)兩邊類型不一致時(shí),不做類型轉(zhuǎn)換,類型不同的一定不等,只有兩者一致才為真。
7.break與continue有什么區(qū)別
- Break 語(yǔ)句:用于跳出循環(huán)。
break 語(yǔ)句跳出循環(huán)后,會(huì)繼續(xù)執(zhí)行該循環(huán)之后的代碼(如果有的話)
for(var i = 1; i< 10; i++){
if(i % 4 === 0){
break;
}
console.log(i); // 1 2 3
}
- Continue 語(yǔ)句
continue 語(yǔ)句中斷循環(huán)中的迭代,如果出現(xiàn)了指定的條件,然后繼續(xù)循環(huán)中的下一個(gè)迭代。
for(var i = 1; i<6; i++){
if(i % 4 === 0){
continue;
}
console.log(i);//1 2 3 5
}
8.void 0 和 undefined在使用場(chǎng)景上有什么區(qū)別
void 會(huì)執(zhí)行后面的表達(dá)式并返回 undefined,但是某些情境下undefined是可以被賦值的,比如在函數(shù)中,這樣的話就不能用undefined來進(jìn)行判斷了。所以用void 0返回undefined來進(jìn)行判斷。既減少了在原形鏈上查找 window.undefined 的時(shí)間,也避免了誤用被修改過的 undefined。
9.以下代碼的輸出結(jié)果是?為什么?
console.log(1+1); // 返回 2同為number類型相加,返回正常運(yùn)算 console.log("2"+"4"); //返回24 ,字符串拼接 console.log(2+"4"); //返回24 ,number 和字符串相加,number轉(zhuǎn)為字符串 console.log(+"4");//返回4 ,只有一個(gè)字符串會(huì)轉(zhuǎn)換成數(shù)字輸出
10. 以下代碼的輸出結(jié)果是?
var a = 1; a+++a; //返回3;(a++)+a=> 1 +2=3; typeof a+2;//返回number2,typeof優(yōu)先級(jí)最高 (typeof a)+2=> number2
11. 以下代碼的輸出結(jié)果是? 為什么
var a = 1; var b = 3; console.log( a+++b );//返回4,(a++)+b=>1+3=4;
12. 遍歷數(shù)組,把數(shù)組里的打印數(shù)組每一項(xiàng)的平方
var arr = [3,4,5]
var arr = [3,4,5]; //方法一 for(var i=0;i<arr.length;i++){ console.log(arr[i]+"的平方是"+Math.pow(arr[i],2)) } //方法二 for(var i=0;i<arr.length;i++){ console.log(arr[i]+"的平方是"+arr[i]*arr[i]) }
13. 遍歷 JSON, 打印里面的值
var obj = {
name: 'hunger',
sex: 'male',
age: 28
}
for(key in obj){ console.log(obj[key]) }
14. 以下代碼輸出結(jié)果是? 為什么 (選做題目)
var a = 1, b = 2, c = 3;
var val = typeof a + b || c >0
console.log(val)//number2 ``
expr1 || expr2: 短路邏輯,如果expr1為``true`` ,返回expr1;
以上運(yùn)算中 Boolean(typeof a + b)=>Boolean("number2") 為true ,所以返回number2
`
var d = 5;
var data = d ==5 && console.log('bb')
console.log(data)//返回undefined``
expr1 && expr2: 短路邏輯,如果expr1為``false ``,返回expr1;
d ==5 為true,所以返回 console.log('bb')
但是最后一步console.log(console.log('bb')) 返回 undefined
原因:內(nèi)部的console.log()為console對(duì)象內(nèi)的log方法,但是沒有返回值
例如:
var obj={
log:function log () { }
}
console.log(obj.log() )//undefined
var obj={
log:function log () { return "123" }
}
console.log(obj.log() )//123
`
var data2 = d = 0 || console.log('haha')
console.log(data2)//返回 undefined
邏輯或的短路邏輯,Boolean(0) 為false,所以返回后者console.log('haha')
最后一步console.log(console.log('haha'))返回undefined;原因:內(nèi)層console.log(‘haha’)方法沒有返回值
`
var x = !!"Hello" + (!"world", !!"from here!!");
console.log(x)//2``
!expr 如果單個(gè)表達(dá)式能轉(zhuǎn)換為true的話返回false,否則返回true.
1. (!"world", !!"from here!!") 逗號(hào)操作符返回返回表達(dá)式的最后一項(xiàng) !!"from here!!" =>true;
2. !!"Hello"=>true
true + true =2;