1. 程式人生 > >JS高級學習筆記(1)- 基本數據類型

JS高級學習筆記(1)- 基本數據類型

java 數值 賦值 現在 lean evel image number com

原始數據

基本數據類型是一種即非對象也無方法的數據。JS中有6中基本類型:stringnumberbooleanundefinedsymbol

多數情況下,基本類型直接代表了最底層的語言實現。

基本類型的值都是不可變的。註意,基本類型本身和被賦值為基本類型的變量區別,變量可以被賦予一個新值,二原值不能像數組、對象以及函數那樣被改變。

示例1

// 使用字符串的方法不會改變一個字符串
let bar = ‘abcd‘;
console.log(bar); // abcd
// 賦值行為可以給一個基本類型一個新值,而不是改變原來的值
let bar1 = bar.toUpperCase()
console.log(bar1); 
// ABCD console.log(bar); // abcd // 使用一個數組的方法可以改變數組 let foo = [] console.log(foo); // [] foo.push(‘plugh‘) console.log(foo); // [ ‘plugh‘ ]

示例2

// 定義基本類型
let foo = 5;

// 定義一個方法
function addTwo(num) {
  // 本地num參數
  num += 2;
}

function addTwo_v2(foo) {
  // 本地foo參數
  foo += 2
}

// 調用第一個函數,並傳入基本類型作為參數
addTwo(foo)
console.log(foo); 
// 5 // 調用第二個方法 addTwo_v2(foo) console.log(foo); // 5

將基本數據作為方法的入參,並沒有將這個原始數據作為入參,而是將這個原始數據復制了一份,創建一個本地副本作為每個方法的入參。

並且,這個復制的副本只存在於該函數的作用域中,我們能夠通過指定在函數中的標識符訪問到它(addTwo中的num,addTwo_v2中的foo)。

綜上所述,函數中的任何操作都不會影響到最初的foo,我們操作的只不過是它的副本。

JavaScript 中的基本類型包裝對象

除了 nullundefined之外,所有基本類型都有其對應的包裝對象:

  • String 為字符串基本類型。

  • Number 為數值基本類型。

  • Boolean 為布爾基本類型。

  • Symbol 為字面量基本類型。

這個包裹對象的valueOf()方法返回基本類型值。

Object.prototype.valueOf()

valueOf() 方法返回指定對象的原始值。

MDN對valueOf()的描述

JavaScript調用valueOf方法將對象轉換為原始值。你很少需要自己調用valueOf方法;當遇到要預期的原始值的對象時,JavaScript會自動調用它。

默認情況下,valueOf方法由Object後面的每個對象繼承。 每個內置的核心對象都會覆蓋此方法以返回適當的值。如果對象沒有原始值,則valueOf將返回對象本身。

JavaScript的許多內置對象都重寫了該函數,以實現更適合自身的功能需要。因此,不同類型對象的valueOf()方法的返回值和返回值類型均可能不同。

技術分享圖片

// Array:返回數組對象本身
var array = ["ABC", true, 12, -5];
console.log(array.valueOf() === array);   // true

// Date:當前時間距1970年1月1日午夜的毫秒數
var date = new Date(2013, 7, 18, 23, 11, 59, 230);
console.log(date.valueOf());   // 1376838719230

// Number:返回數字值
var num =  15.26540;
console.log(num.valueOf());   // 15.2654

// 布爾:返回布爾值true或false
var bool = true;
console.log(bool.valueOf() === bool);   // true

// new一個Boolean對象
var newBool = new Boolean(true);
// valueOf()返回的是true,兩者的值相等
console.log(newBool.valueOf() == newBool);   // true
// 但是不全等,兩者類型不相等,前者是boolean類型,後者是object類型
console.log(newBool.valueOf() === newBool);   // false

// Function:返回函數本身
function foo(){}
console.log( foo.valueOf() === foo );   // true
var foo2 =  new Function("x", "y", "return x + y;");
console.log( foo2.valueOf() );
/*
? anonymous(x,y
) {
return x + y;
}
*/

// Object:返回對象本身
var obj = {name: "張三", age: 18};
console.log( obj.valueOf() === obj );   // true

// String:返回字符串值
var str = "http://www.xyz.com";
console.log( str.valueOf() === str );   // true

// new一個字符串對象
var str2 = new String("http://www.xyz.com");
// 兩者的值相等,但不全等,因為類型不同,前者為string類型,後者為object類型
console.log( str2.valueOf() === str2 );   // false

toString()

Boolean.prototype.toString()

toString() 方法返回指定的布爾對象的字符串形式。

let flag = new Boolean(true);
console.log(flag.toString()) // true

let flag1 = new Boolean(1);
console.log(flag1.toString()) // true

Array.prototype.toString()

toString()返回一個字符串,表示指定的數組及其元素。

let array = [‘abc‘, true, 12, undefined, ‘ok‘]
console.log(array.toString()); // abc,true,12,,ok

Function.prototype.toString()

toString() 方法返回一個表示當前函數源代碼的字符串。

function fun(num) {
  num += 5
}

console.log(fun.toString());
/**
 * function fun(num) {  num += 5 }
 */

Object.prototype.toString()

toString() 方法返回一個表示該對象的字符串。

let obj = { name: ‘houfee‘}
console.log(obj.toString()); // [object Object]

Number強制轉換對象

let a={name:123};
console.log(Number(a)); // NaN
    /* 
     * JS對象強制類型轉換
     * 主要調用 object.valueOf() 和 object.toString() 方法
     * 1.先調用 object 的 valueOf() 方法
     * 2.判斷返回值 是否為 基礎數據類型?
     * 3.是!則轉換規則按照相應數據類型的規則對其進行轉換
     * 4.不是!在返回值的基礎上繼續調用 toString() 方法
     * 5.判斷調用 toString() 方法返回值是否為 基礎數據類型
     * 6.是!則轉換規則按照相應數據類型的規則對其進行轉換
     * 7.不是!報錯:
     * */

技術分享圖片

現在我們用自定義方法覆蓋toString()方法:

a.toString = function () {return {name: ‘newName‘}} // 讓toString方法返回值為 復雜數據類型
a.toString() // 調用覆蓋的方法
Number(a) // 報錯

技術分享圖片

現在驗證讓toString方法返回值為 基礎數據類型

a.toString = function () {return ‘321‘} // 讓toString方法返回值為 復雜數據類型
a.toString() // 調用覆蓋的方法
Number(a) // 321

技術分享圖片

所以Number強制轉換對象的過程即為如上7步

String()強制轉換對象

let b = {name: ‘houfee‘}
console.log(String(b)); // [object Object]
let c = []
console.log(String(c)); // 空字符串
let d = {}
console.log(String(d)); // [object Object]

技術分享圖片

1.先調用對象的toString方法

2.判斷該方法的返回值是否為基礎數據類型(Number,String,Boolean,Undefined,Null)

3.若返回值為基礎數據類型,則轉換規則按照相應數據類型的轉換規則對其進行轉換

4.若返回值不為基礎數據類型,則在該返回值的基礎上繼續調用valueOf方法

5.判斷valueOf的返回值是否為基礎數據類型

6.判斷是否為基礎數據類型,若是基礎數據類型則進行操作3

7.若仍舊不為基礎數據類型則報錯

String與Number的區別則在於

  • Number是先調用valueOf再調用toString

  • 而String是先調用toString再調用valueOf

Boolean強制轉換對象

轉換為false的有undefined、null、‘‘、0、NaN

面試題

    console.log({}); // {}
    console.log(Number({})); // NaN、
    console.log(String({})); // [object Object]
    console.log(Boolean({})); // true

    console.log([]); // []
    console.log(Number([])); // 0
    console.log(String([])); // 空字符串
    console.log(Boolean([])); // true

    console.log({} + {}) // [object Object][object Object]
    console.log({} + []) // [object Object]
    console.log([] + {}) // [object Object]
    console.log([] + []) // 空字符串

JS高級學習筆記(1)- 基本數據類型