JavaScript 定義了幾種數據類型? 哪些是原始類型?哪些是復雜類型?原始類型和復雜類型的區別是什么?
- JS共有6種數據類型。
- 數值(number):整數和小數(比如1和3.14)
- 字符串(string):字符組成的文本(比如”Hello World”)
- 布爾值(boolean):true(真)和false(假)兩個特定值
- undefined:表示“未定義”或不存在,即由于目前沒有定義,所以此處暫時沒有任何值
- null:表示無值,即此處的值就是“無”的狀態。
- 對象(object):各種值組成的集合
- 其中:number、string、boolean、undefined、null屬于原始類型(基本類型);object屬于復雜類型(引用類型);
- 基本類型與引用類型的區別:
- 基本數據類型的值是不可變的,而引用類型的值是可以改變的
- 基本數據類型不可以添加屬性和方法,而引用類型可以添加屬性和方法
- 基本數據類型的賦值是簡單賦值,從一個變量向另一個變量賦值基本類型的值,會直接把該值復制到為新變量分配的位置上;而引用類型的賦值是對象引用
- 基本數據類型的比較是值的比較,而引用類型的比較是引用的比較
- 基本數據類型是存放在棧區的;而引用類型是將對象的引用保存在棧區,對象實體保存在堆區中的
typeof和instanceof的作用和區別?
typeof
-
typeof操作符返回一個字符串,指示未經計算的操作數的類型。通常用來判斷基本類型的值
語法:typeof operand operand 是一個表達式,表示對象或原始值,其類型將被返回。
-
typeof除對null外的基本類型使用會返回代表這個類型的字符串,如:
typeof 1 -> "number" typeof "1" -> "string" typeof null -> "object"
-
typeof除對function以外的所有的引用類型使用都會返回"object", 如:
typeof {} -> "object" typeof [] -> "object" function f(){} typeof f -> "function"
instanceof
-
instanceof 運算符用來測試一個對象在其原型鏈中是否存在一個構造函數的 prototype 屬性。通常用來判斷一個對象是否屬于某個引用類型
語法:object instanceof constructor object 要檢測的對象. constructor 某個構造函數
-
如:
[] instanceof Array -> true // 定義構造函數 function C(){} function D(){} var o = new C(); // true,因為 Object.getPrototypeOf(o) === C.prototype o instanceof C; // false,因為 D.prototype不在o的原型鏈上 o instanceof D; // true,因為Object.prototype.isPrototypeOf(o)返回true;(Object是所有引用類型的根類型) o instanceof Object;
如何判斷一個變量是否是數字、字符串、布爾、函數
-
對于這些數據類型都可以用typeof判斷,如:
typeof 1 === "number" -> true typeof "1" === "string" -> true function f(){} typeof f === "function" -> true
NaN是什么? 有什么特別之處?
- 全局屬性 NaN 表示 Not-A-Number 的值。
- NaN 屬性的初始值就是 NaN,和 Number.NaN 的值一樣。在現代瀏覽器中(ES5中), NaN 屬性是一個不可配置(non-configurable),不可寫(non-writable)的屬性。
- 在編碼很少直接使用到 NaN。通常都是在計算失敗時,作為 Math 的某個方法的返回值出現的(例如:Math.sqrt(-1))或者嘗試將一個字符串解析成數字但失敗了的時候(例如:parseInt("blabla"))。
- 判斷一個值是否是NaN
-
等號運算符(== 和 ===) 不能被用來判斷一個值是否是 NaN。必須使用 Number.isNaN() 或 isNaN() 函數。在執行自比較之中:NaN,也只有NaN,比較之中不等于它自己。
NaN === NaN; // false Number.NaN === NaN; // false isNaN(NaN); // true isNaN(Number.NaN); // true
-
如何把非數值轉化為數值?
-
1.使用Number()函數。
Number(true) // 1 Number("1") // 1 Number("1.23") // 1.23 // 當字符串中有字母時返回NaN Number("a") // NaN Number("123e3") // NaN
-
2.parseInt(),用于將字符串轉為整數。
parseInt('123') // 123 parseInt(' 81') // 81 parseInt(1.23) // 1 // 當字符串中有其它字母時返回字母前的數字,當第一個字符為字母或不是字符串時返回NaN parseInt('15e2') // 15 parseInt('abc') // NaN
-
3.parseFloat(),用于將一個字符串轉為浮點數。
parseFloat('3.14') // 3.14 // 當字符串中有其它字母時返回字母前的數字,當第一個字符為字母或不是字符串時返回NaN parseInt('15e2') // 15 parseInt('abc') // NaN
-
4.在非數值前添加一個"+"號
// 行為與Number()函數類似 +"1" // 1 +true //1 +"1.1" //1.1 +"123a" //NaN
==與===有什么區別
- ES5提供兩種不同的值比較操作:
- 嚴格相等 ("triple equals" 或 "identity"),使用 ===
- 寬松相等 ("double equals") ,使用 ==
- 嚴格相等 ===
- 全等操作符比較兩個值是否相等,兩個被比較的值在比較前都不進行隱式轉換。如果兩個被比較的值具有不同的類型,這兩個值是不全等的。否則,如果兩個被比較的值類型相同,值也相同,并且都不是 number 類型時,兩個值全等。最后,如果兩個值都是 number 類型,當兩個都不是 NaN,并且數值相同,或是兩個值分別為 +0 和 -0 時,兩個值被認為是全等的。全等操作符認為 NaN 與其他任何值都不全等,包括它自己。
如:1 === "1" //false
- 全等操作符比較兩個值是否相等,兩個被比較的值在比較前都不進行隱式轉換。如果兩個被比較的值具有不同的類型,這兩個值是不全等的。否則,如果兩個被比較的值類型相同,值也相同,并且都不是 number 類型時,兩個值全等。最后,如果兩個值都是 number 類型,當兩個都不是 NaN,并且數值相同,或是兩個值分別為 +0 和 -0 時,兩個值被認為是全等的。全等操作符認為 NaN 與其他任何值都不全等,包括它自己。
- 非嚴格相等 ==
- 相等操作符比較兩個值是否相等,在比較前將兩個被比較的值轉換為相同類型。在轉換后(等式的一邊或兩邊都可能被轉換),最終的比較方式等同于全等操作符 === 的比較方式。 相等操作符滿足交換律。如:1 == "1" // true
break與continue有什么區別
-
break 語句可用于跳出循環。break 語句跳出循環后,會繼續執行該循環之后的代碼(如果有的話)
for (var i = 1; i < 10; i++) { if (i % 4 === 0) { break } console.log(i) } // 輸出1,2,3
-
continue 語句中斷循環中的迭代,如果出現了指定的條件,然后繼續循環中的下一個迭代。
for (var i = 1; i < 10; i++) { if (i % 4 === 0) { continue } console.log(i) } // 輸出1,2,3,5,6,7,9
void 0 和 undefined在使用場景上有什么區別
- void 會執行后面的表達式并返回 undefined,但是某些情境下undefined是可以被賦值的,比如在函數中,這樣的話就不能用undefined來進行判斷了。所以用void 0返回undefined來進行判斷。既減少了在原形鏈上查找 window.undefined 的時間,也避免了誤用被修改過的 undefined。
以下代碼的輸出結果是?為什么?
console.log(1+1);
// 2 當+兩邊都是數字表示兩個數字相加
console.log("2"+"4");
// "24" 當+兩邊有一個是字符串時表示字符串連接
console.log(2+"4");
// "24" 同上
console.log(+"4");
// 4 當+放在一個值前面時,表示將這個值轉換為數值
以下代碼的輸出結果是?
var a = 1;
a+++a;
typeof a+2;
// "number2"
// 解析:(a++)+a -> 3; (typeof a)+2 -> "number2"
以下代碼的輸出結果是? 為什么
var a = 1;
var b = 3;
console.log( a+++b );
// 4, 因為++的優先級高于+,所以(a++)+b,a++返回a的值,所以:1+3=4
遍歷數組,把數組里的打印數組每一項的平方
var arr = [3,4,5]
for (var i = 0, len = arr.length; i < len; i++) {
console.log(arr[i] * arr[i])
}
遍歷 JSON, 打印里面的值
var obj = {
name: 'hunger',
sex: 'male',
age: 28
}
for (var x in obj) {
console.log(obj[x])
}
以下代碼輸出結果是? 為什么
var a = 1, b = 2, c = 3;
var val = typeof a + b || c >0
console.log(val)
// "number2" ,解析:typeof的優先級高于+ ,所以typeof a + b =》"number2",因為當||左邊的值為true時返回這個值,而除了空字符串外所有字符串的布爾值為true,所以直接返回"number2"
var d = 5;
var data = d ==5 && console.log('bb')
console.log(data)
// undefined, 解析:d == 5為true,當&&左邊的值為true時返回它右邊的值,而console.log的返回值為undefined。
var data2 = d = 0 || console.log('haha')
console.log(data2)
// undefined, 解析:d = 0返回值為undefined,它的布爾值為false,當||左邊的值為false時返回它右邊的值,而console.log的返回值為undefined。
var x = !!"Hello" + (!"world", !!"from here!!");
console.log(x)
// 2, 解析:!表示取反,!!相當于將一個值轉化為布爾值,非空字符串的布爾值為true,所以!!"Hello"=》true;,操作符返回后面的值,同上可知!!"from here!!"=》true;當+兩邊的值為布爾值時,它會將他們轉換為數值,true轉換為數值得到1,所以x = 1 + 1.