JS類型轉(zhuǎn)換

有一道面試題是:

實現(xiàn)一個函數(shù),運算結(jié)果可以滿足如下預(yù)期結(jié)果:
add(1)(2) //3
add(1,2,3)(10) //16
add(1)(2)(3)(4)(5) //15

其中一種解法:

function add(){
    console.log("進入add");
    var args = Array.prototype.slice.call(arguments);
    console.log(args);

    var fn = function () {
        var arg_fn = Array.prototype.slice.call(arguments);
        console.log('調(diào)用fn');
        console.log(arg_fn);
        return add.apply(null,args.concat(arg_fn));
    }

    fn.valueOf = function () {
        console.log('調(diào)用valueOf()');
        return args.reduce(function (a,b) {
            console.log('調(diào)用valueOf(),返回%d+%d=%d',a,b,a+b);
            return a+b;
        })
    }
    return fn;
}

console.log(add(2)(3,4);
//    add(1)(2);

//    add(3,4,5)(6);

剛看到這個解決辦法會覺得很奇怪,fn.valueOf()沒有被調(diào)用過,這樣寫怎么能成功解決呢?

原因:
JavaScript調(diào)用valueOf()方法把對象轉(zhuǎn)換成原始類型的值(數(shù)值、字符串和布爾值)。并且往往valueOf()方法會被JavaScript自動調(diào)用。

valueOf()和toString()在特定場合下會自動調(diào)用!!!

下面來說一說類型轉(zhuǎn)換:

原始類型

JavaScript的幾種原始類型,除去Object和Symbol,有以下幾種:

  • Number
  • String
  • Boolean
  • Undefined
  • Null

在JavaScript進行對比或者各種運算的時候會把對象轉(zhuǎn)換成這些類型,從而進行后續(xù)操作。

String類型轉(zhuǎn)換

在某個操作或者運算需要字符串而該對象又不是字符串的時候,會觸發(fā)該對象的String轉(zhuǎn)換,會將非字符串的類型嘗試自動轉(zhuǎn)換為String類型。系統(tǒng)內(nèi)部會自動調(diào)用toString函數(shù)。

var obj = {name:'Wonder'};
var str = '123'+obj;
console.log(str); //123[object Object]

轉(zhuǎn)換規(guī)則:

  1. 如果toString方法存在并且返回原始類型,返回toString的結(jié)果。
  2. 如果toString方法不存在或者返回的不是原始類型,調(diào)用valueOf方法,如果valueOf方法存在,并且返回的是原始類型數(shù)據(jù),返回valueOf的結(jié)果
  3. 其他情況,拋出錯誤。

上面的例子實際上是:

var obj = {name:'Wonder'};
var str = '123'+obj.toString();
//obj.toString的值是[object Object]

如果我們改寫對象的toString,valueOf方法:

var obj = {
    toString:function(){
        console.log('調(diào)用了toString');
        return {};
    },
    valueOf:function(){
        console.log('調(diào)用了valueOf');
        return '10';
    }
}
console.log(obj);
//調(diào)用了toString
//調(diào)用了valueOf
//10

Number類型轉(zhuǎn)換

以下會發(fā)生Number類型轉(zhuǎn)換:

  1. 調(diào)用Number()函數(shù),強制進行Number類型轉(zhuǎn)換
  2. 調(diào)用Math.sqrt()這類參數(shù)需要Number類型的方法
  3. obj == 1,進行對比的時候
  4. obj+1,進行運算的時候

與String類型轉(zhuǎn)換相似,但是Number類型剛好反過來,先查詢自身的valueOf方法,再查詢自己toString方法。
轉(zhuǎn)換規(guī)則:

  1. 如果valueOf方法存在并且返回原始類型,返回valueOf的結(jié)果。
  2. 如果valueOf方法不存在或者返回的不是原始類型,調(diào)用toString方法,如果toString方法存在,并且返回的是原始類型數(shù)據(jù),返回toString的結(jié)果
  3. 其他情況,拋出錯誤。

Boolean轉(zhuǎn)換

什么時候會進行布爾轉(zhuǎn)換呢?

  • 布爾比較時
  • if(obj),while(obj)等判斷時

轉(zhuǎn)換規(guī)則:
除了下述 6 個值轉(zhuǎn)換結(jié)果為 false,其他全部為 true:

  • undefined
  • null
  • -0
  • 0或+0
  • NaN
  • ”(空字符串)

參考:一道面試題引發(fā)的對 javascript 類型轉(zhuǎn)換的思考

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

推薦閱讀更多精彩內(nèi)容