Object.prototype.valueOf()和Object.prototype.toString()

valueOf() 方法用來把對象轉換成原始類型的值(數值、字符串和布爾值)前端

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

  • 原始類型
Number
String
Boolean
Undefined
Null
  • String類型轉換
  1. 若是 toString 方法存在而且返回原始類型,返回 toString 的結果。
  2. 若是 toString 方法不存在或者返回的不是原始類型,調用 valueOf 方法,若是 valueOf 方法存在,而且返回原始類型數據,返回 valueOf 的結果。
  3. 其餘狀況,拋出錯誤。
var obj = {name: 'Coco'};
var str = '123' + obj;
console.log(str);  // 123[object Object]

上面的代碼等價於:微信

var obj = {name: 'Coco'};
var str = '123' + obj.toString();

假設是數組:app

var arr = [1, 2];
var str = '123' + arr;
console.log(str); // 1231,2

上面 + arr ,因爲這裏是個字符串加操做,後面的 arr 須要轉化爲一個字符串類型,因此實際上是調用了 + arr.toString() 。函數

可是,對象的toString和valueOf方法能夠本身改寫:spa

var obj = {
    toString: function() {
        console.log('調用了 obj.toString');
        return {};
    },
    valueOf: function() {
        console.log('調用了 obj.valueOf')
        return '110';
    }
}
 
alert(obj);
// 調用了 obj.toString(toString方法沒有返回原始類型,接着調用valueOf方法)
// 調用了 obj.valueOf
// 110

若是valueOf方法也不返回原始類型的話,就會出現下面的狀況:prototype

var obj = {
    toString: function() {
        console.log('調用了 obj.toString');
        return {};
    },
    valueOf: function() {
        console.log('調用了 obj.valueOf')
        return {};
    }
}
 
alert(obj);
// 調用了 obj.toString
// 調用了 obj.valueOf
// Uncaught TypeError: Cannot convert object to primitive value
  • Number類型轉換
  1. 若是 valueOf 存在,且返回原始類型數據,返回 valueOf 的結果。
  2. 若是 toString 存在,且返回原始類型數據,返回 toString 的結果。
  3. 其餘狀況,拋出錯誤。
var obj = {
    valueOf: function() {
        console.log('調用 valueOf');
        return 5;
    }
}
 
console.log(obj + 1);
// 調用 valueOf
// 6
var obj = {
    valueOf: function() {
        console.log('調用 valueOf');
        return {};
    },
    toString: function() {
        console.log('調用 toString');
        return 10;
    }
}
 
console.log(obj + 1);
// 調用 valueOf
// 調用 toString
// 11
var obj = {
    valueOf: function() {
        console.log('調用 valueOf');
        return {};
    },
    toString: function() {
        console.log('調用 toString');
        return {};
    }
}
 
console.log(obj + 1);
// 調用 valueOf
// 調用 toString
// Uncaught TypeError: Cannot convert object to primitive value
  • Boolean類型轉換

何時會進行布爾轉換呢:code

  1. 布爾比較時對象

  2. if(obj) , while(obj) 等判斷時blog

簡單來講,除了下述 6 個值轉換結果爲 false,其餘所有爲 true:

undefined
null
-0
0或+0
NaN
」(空字符串)
Boolean(undefined) // false
Boolean(null) // false
Boolean(0) // false
Boolean(NaN) // false
Boolean('') // false
  • Function轉換
function test() {
    var a = 1;
    console.log(1);
}
test; // 這裏其實自行調用了函數的valueOf方法
function test() {
    var a = 1;
    console.log(1);
}
test.valueOf = function() {
    console.log('調用 valueOf 方法');
    return 2;
}
 
test;
// 輸出以下:
// 調用 valueOf 方法
// 2
test.valueOf = function() {
    console.log('調用 valueOf 方法');
    return {};
}
 
test.toString= function() {
    console.log('調用 toString 方法');
    return 3;
}
 
test;
// 輸出以下:
// 調用 valueOf 方法(不是返回的原始類型,繼續尋找toString方法進行調用)
// 調用 toString 方法
// 3
function add () {
    console.log('進入add');
    var args = Array.prototype.slice.call(arguments);
 
    var fn = function () {
        var arg_fn = Array.prototype.slice.call(arguments);
        console.log('調用fn');
        return add.apply(null, args.concat(arg_fn));
    }
 
    // 此處的valueOf方法也能換成toString方法
    fn.valueOf = function () {
        console.log('調用valueOf');
        return args.reduce(function(a, b) {
            return a + b;
        })
    }
 
    return fn;
}

add(1)(2)(3);
// 輸出以下:
// 進入add
// 調用fn
// 進入add
// 調用fn
// 進入add
// 調用valueOf
// 6
// 前面都是合併參數,到最後返回fn函數,此時才調用fn.valueOf方法

 (轉自微信公衆號:前端大全)

相關文章
相關標籤/搜索