JavaScript 變數型別
阿新 • • 發佈:2019-01-11
變數型別
JavaScript 中的變數型別分為值型別(又稱為簡單型別、基本資料型別)以及引用型別。
【值型別】:
- Number
- String
- Undefined
- Null
- Boolean
【引用型別】:
- Object
- Array
- Function
值型別和引用型別的區別
- 儲存方式的不同:每宣告一個值型別變數,都會在記憶體中單獨分配出一塊區域用以儲存,變數之間不會相互影響;而引用型別返回的是儲存地址,因此若是變數之間的賦值,實際是將地址的引用進行賦值。
// 值型別 var a = 100, b = a; console.log(a); // 100 console.log(b); // 100 b = 50; console.log(a); // 100 console.log(b); // 50 // 引用型別 var a = { number: 100 }, b = a; console.log(a.number); // 100 console.log(b.number); // 100 b.number = 50; console.log(a.number); // 50 console.log(b.number); // 50
typeof 運算子
typeof 運算子把型別資訊當作字串返回。
var number = 100, string = "Hello", boolean = true, variable, variable2 = null, fun = function() {}, object = {}, array = []; console.log(typeof number); // "number" console.log(typeof string); // "string" console.log(typeof boolean); // "boolean" console.log(typeof variable); // "undefined" console.log(typeof variable2); // "object" console.log(typeof fun); // "function" console.log(typeof object); // "object" console.log(typeof array); // "object"
- typeof 只能區分值型別:number、string、undefined、boolean。
- 引用型別除函式外,物件和陣列都為 object(注意,基本型別中的 null 也為 object)。
- 函式在JS中為一等公民,因此能夠被 typeof 識別為 function。
如何區分陣列?
- 鴨式辨型法:
var array = [1, 2, 3]; if (typeof array.sort === "function") { // 思想:判斷當前物件是否擁有陣列物件專有的 sort 函式。 console.log("haha"); } // 缺陷 var array = { data: [], sort: function() {} } if (typeof array.sort === "function") { // 也能成功執行 console.log("hoho"); }
- Kangax 方案:
var array = [1, 2, 3];
if (Object.prototype.toString.call(array) === "[object Array]") {
// 思想:呼叫某個值的內建 toString() 方法在所有瀏覽器中都會返回標準的字串結果。
// 對於陣列來說,返回的字串為 “[object Array]”.
console.log("haha");
}
// 缺陷:對於自定義物件使用這種方法會存在問題,比如內建 JSON 物件將返回 “[object JSON]”
- isArray() 方法:
var array = [1, 2, 3];
if (Array.isArray(array)) {
// ECMAScript5 將 Array.isArray() 正式引入 JavaScript。
console.log("haha");
}
// 相容低版本寫法
function isArray(value) {
if( typeof Array.isArray === "function") {
return Array.isArray(value);
} else {
return Object.prototype.toString.call(value) === "[object Array]";
}
}
型別轉換
JavaScript 是一種弱型別語言,所以無法確定變數儲存具體型別的值,並且變數的型別也可以隨時發生變換。
轉換規則
【示例】:
var a = 100,
b = "50",
c = true,
d = null,
e,
f = function() {},
g = {},
h = [],
i = { data: 1 },
j = [1, 2];
// Number
console.log("Number + String", a + b); // "10050"
console.log("Number + Boolean", a + c); // 101
console.log("Number + Null", a + d); // 100
console.log("Number + Undefined", a + e); // NaN
console.log("Number + Function", a + f); // 100function() {}
console.log("Number + Object(Empty)", a + g); // 100[object Object]
console.log("Number + Array(Empty)", a + h); // 100
console.log("Number + Object", a + i); // 100
console.log("Number + Array", a + j); // 100
// 引用型別
console.log(f.toString()); // function() {}
console.log(g.toString()); // [object Object]
console.log(h.toString()); //
console.log(i.toString()); // [object Object]
console.log(j.toString()); // 1,2
// String
console.log("String + Boolean", b + c); "50true"
console.log("String + Null", b + d); "50null"
console.log("String + Undefined", b + e); "50undefined"
console.log("String + Function", b + f); "50function() {}"
console.log("String + Object", b + g); "50[object Object]"
console.log("String + Array", b + h); "50"
// Boolean
console.log("Boolean + Null", c + d); "1"
console.log("Boolean + Undefined", c + e); "NaN"
console.log("Boolean + Function", c + f); "truefunction() {}"
console.log("Boolean + Object", c + g); "true[object Object]"
console.log("Boolean + Array", c + h); "true"
// Null
console.log("Null + Undefined", d + e); "NaN"
console.log("Null + Function", d + f); "nullfunction() {}"
console.log("Null + Object", d + g); "null[object Object]"
console.log("Null + Array", d + h); "null"
// Undefined
console.log("Undefined + Function", e + f); "undefinedfunction() {}"
console.log("Undefined + Object", e + g); "undefined[object Object]"
console.log("Undefined + Array", e + h); "undefined"
【規則】:
- 所有型別都能夠轉換為 String 型別。引用型別會呼叫 toString() 方法進行型別轉換。而值型別則將值轉換為 String 型別(100 => “100”,true => “true”)。
- 型別轉換遵循向運算元型別優先順序高的一方轉換的原則。例如,Number 和 String 相加,將 Number 轉換為 String。
- Boolean 和 Null 型別可以轉換為 Number 型別(true:1,false:0,null:0)。
- Undefined 型別無法轉換為 Number 型別,因此和 Number 型別執行加算術運算時會得到 NaN。
【注意】:當運算元中不存在 String 型別,+ 表示算術運算中的加法運算,因此在進行型別轉換時,會轉換為 Number 型別。若存在 String 型別,+ 表示連字元操作,因此會轉換為 String 型別。在判斷型別轉換時,必須要明確當前具體要執行的操作。
【問】:為什麼 Number 型別和引用型別相加時,最後的結果卻是 String?按照上述規則中的“型別轉換遵循向運算元型別優先順序高的一方轉換的原則”,不應該是將引用型別轉化為 Number 型別嗎?
【答】:引用型別在執行 + 操作時,會呼叫其自身的 toString() 方法,此時引用型別已經轉換為 String。而 String 的優先順序大於 Number,會將 Number 轉換為 String,因此最後的結果是 String。
【Boolean 型別轉換規則】:
型別 | true | false |
---|---|---|
String | 非空字串 | 空字串 “” |
Number | 非 0 和 NaN | 0 和 NaN |
Undefined | 不適用 | Undefined |
Null | 不適用 | Null |
Object | 任何物件 | 不適用 |
Array | 任何陣列 | 不適用 |
Function | 任何函式 | 不適用 |
【示例】:
var a = 100,
a_2 = 0,
b = "50",
b_2 = "",
c = true,
c_2 = false,
d = null,
e,
f = function() {},
g = {},
h = [],
i = { data: 1 },
j = [1, 2];
console.log(!!a); // true
console.log(!!a_2); // false
console.log(!!b); // true
console.log(!!b_2); // false
console.log(c); // true
console.log(c_2); // false
console.log(!!d); // false
console.log(!!e); // false
console.log(!!f); // true
console.log(!!g); // true
console.log(!!h); // true
console.log(!!i); // true
console.log(!!j); // true
強制型別的場景
- 字串拼接
- == 等於運算子
- if () 條件判斷
- 邏輯運算子
小技巧:轉換為 Boolean 型別
【示例】:
var a = 100;
a = !!a;
// 先通過取反操作,將其轉換為 Boolean 型別
// 然後再取反,獲得正確的值