數據型別分類
+ 基本數據型別 【7】
+ 參照數據型別 【2】
+ isNaN、NaN、Infinity
學習之前先來看一道面試題,看下這道題是否能做對。
let res = parseFloat('left:200px');
if(res===200){
alert(200);
}else if(res===NaN){
alert(NaN);
}else if(typeof res==='number'){
alert('number');
}else{
alert('Invalid Number');
}
typeof 是按照二進制的底層機制 機製來檢測數據型別的,預設以000開頭的都是物件,而null全是0,所以把null看作物件數據型別。
結合程式碼詳解上述知識點:
//NaN是數位型別,不是有效數位
console.log(typeof NaN); //=>"number"
//NaN和任何值都不相等,包括它自己
console.log(NaN == NaN); //=>false
//想要判斷一個值是否爲NaN,用方法isNaN([val])
let n = 10;
if (isNaN(n)) {
// 條件成立:證明它真的是非有效數位
}
//Object.is([val1],[val2]):檢測兩個值是否相等
console.log(Object.is(NaN, NaN)); //=>true
Object.is([val1],[val2]):檢測兩個值是否相等,返回一個 Boolean 型別標示兩個參數是否是同一個值。
Object.is() 方法判斷兩個值是否爲同一個值。如果滿足以下條件則兩個值相等:
- 都是 undefined
- 都是 null
- 都是 true 或 false
- 都是相同長度的字串且相同字元按相同順序排列
- 都是相同對象(意味着每個物件有同一個參照)
- 都是數位且
—— 都是 +0
—— 都是 -0
—— 都是 NaN
—— 或都是非零而且非 NaN 且爲同一個值與== 運算不同。 == 運算子在判斷相等前對兩邊的變數(如果它們不是同一型別) 進行強制轉換 (這種行爲的結果會將 「」 == false 判斷爲 true), 而 Object.is不會強制轉換兩邊的值。
與=== 運算也不相同。 === 運算子 (也包括 == 運算子) 將數位 -0 和 +0 視爲相等 ,而將Number.NaN 與NaN視爲不相等.
let val = Symbol('00');
console.log(val == val); //=>true
console.log(Symbol('AA') == Symbol('AA')); //=>false
let a = NaN;
console.log(a == a); //=>false
JS中超過這個最大安全數之後再計算就不準 不準確了,如下圖:
Number.MAX_SAFE_INTEGER;//=>9007199254740991
JS中的最大安全數,超過這個值的,需要用bigint處理(在一個數值後面加n就是bigint型別)
現在來看下最開始的面試題,相信你一定得出正確答案了,就是【‘number’】。
首先思考下:數據型別爲啥分成兩大型別,兩種型別有啥區別?
先來看一道面試題,由此題來引申出思考題的答案
var a = 12;
var b = a;
b = 13;
console.log(a); //12
var a = {
n: 12
};
var b = a;
b.n = 13;
console.log(a.n);
var a = {
n: 12
};
var b = a;
b = {
n: 13
};
console.log(a.n);
圖解一:
var a = 12;
var b = a;
b = 13;
console.log(a); //12
圖解二:
var a = {
n: 12
};
var b = a;
b.n = 13;
console.log(a.n);
圖解三:
var a = 12;
var b = a;
b = 13;
console.log(a); //12
第一:JS程式碼可以執行的環境:
第二:瀏覽器之所以能夠執行程式碼,是因爲提供了-個供程式碼執行的環境,即棧記憶體 ECStack(Execution Context Stack),棧記憶體就是在計算機中分配出來的一塊記憶體
第三:程式碼執行分爲:全域性程式碼、函數中程式碼、私有塊中的程式碼…
不同環境下的程式碼執行的時候都有自己的上下文(環境)——EC(Execution Context)執行上下文
第四:當前環境上下文形成後會有一個進棧的過程【JS程式碼在瀏覽器中執行,首先瀏覽器開闢一個棧記憶體即 ESCStack執行環境棧;全域性程式碼在執行前先形成自己的EC即執行上下文,這個執行上下文形成後會有一個進棧過程即進入瀏覽器分配的這塊記憶體[ECStack:執行環境棧],函數執行的時候同理】
第五:程式碼在當前上下文中執行的時候,建立的變數總會儲存在當前上下文中指定的變數物件[VO (Varibale Object)]中,所以變數物件就是用來儲存當前上下文中建立的變數的。
第六:程式碼執行之前先進行變數提升/詞法解析……
第七:等號賦值的詳細過程:var a=12;.
var a;宣告變數,但是在變數提升階段並沒有賦值,所以是未定義,預設值是undefined。等號每次賦值都會重新建立一個值。
【基本數據型別是按值操作[在棧記憶體中],參照數據型別都是按照地址來操作[堆記憶體中]】
//example 1
var a={}, b='0', c=0;
a[b]='你好';
a[c]='世界';
console.log(a[b]);
---------------------
//example 2
var a={}, b=Symbol('1'), c=Symbol('1');
a[b]='你好';
a[c]='世界';
console.log(a[b]);
---------------------
//example 3
var a={}, b={n:'1'}, c={m:'2'};
a[b]='你好';
a[c]='世界';
console.log(a[b]);
var a = {n: 1};
var b = a;
a.x = a = {n: 2};
console.log(a.x);
console.log(b);
var x = [12, 23];
function fn(y) {
y[0] = 100;
y = [100];
y[1] = 200;
console.log(y);
}
fn(x);
console.log(x);