js中的valueOf和toString的隱式調(diào)用

柯里化函數(shù)

實現(xiàn)一個函數(shù):
add(1,2)(3) -> 6
add(1)(2)(3) -> 6
add(1)(2)(3,4) -> 10

function add() {
  let args = Array.from(arguments)
  let _add = function () {
    args.push(...arguments)
    return _add
  }
  _add.toString = function () {
    return args.reduce(function (a,b) {
      return a + b
    })  
  }
  return _add
}

我們發(fā)現(xiàn) add 函數(shù)中 _add.toString 并沒有被調(diào)用怎么會執(zhí)行呢,其實 toString 被隱士調(diào)用了,來看下文分析

隱式調(diào)用

我們來做個試驗驗證 每個對象的toString和valueOf方法都可以被改寫,每個對象執(zhí)行完畢,如果被用以操作JavaScript解析器就會自動調(diào)用對象的toString或者valueOf方法

let obj = {
  i: 10,
  toString: function() {
    console.log('toString');
    return this.i;
  },
  valueOf: function() {
    console.log('valueOf');
    return this.i;
  }
}
alert(obj );// 10 toString
alert(+obj ); // 10 valueOf
alert(''+obj ); // 10 valueOf
alert(String(obj )); // 10 toString
alert(Number(obj )); // 10  valueOf
alert(obj == '10'); // true valueOf
alert(obj === '10'); // false

我們可能會感覺,如果轉換為字符串時調(diào)用toString方法,如果是轉換為數(shù)值時則調(diào)用valueOf方法, === 不做隱式轉換(數(shù)據(jù)類型不同直接判斷為false)

我們接著做試驗

var bb = {
  i: 10,
  toString: function() {
    console.log('toString');
    return this.i;
  }
}
 
alert(bb);// 10 toString
alert(+bb); // 10 toString
alert(''+bb); // 10 toString
alert(String(bb)); // 10 toString
alert(Number(bb)); // 10 toString
alert(bb == '10'); // true toString

看著很順 都調(diào)用了 toString , 再看下 valueOf

var cc= {
   i: 10,
   valueOf: function() {
     console.log('valueOf');
     return this.i;
   }
 }
 
 alert(cc);// [object Object]
 alert(+cc); // 10 valueOf
 alert(''+cc); // 10 valueOf
 alert(String(cc)); // [object Object]
 alert(Number(cc)); // 10 valueOf
 alert(cc== '10'); // true valueOf

我們會發(fā)現(xiàn)有些不同,有些童鞋可能懷疑,對于那個[object Object],估計是從Object那里繼承過來的,我們再去掉它看看

Object.prototype.toString = null;
 
var dd= {
  i: 10,
  valueOf: function() {
    console.log('valueOf');
    return this.i;
  }
}
 
alert(dd);// 10 valueOf
alert(+dd); // 10 valueOf
alert(''+dd); // 10 valueOf
alert(String(dd)); // 10 valueOf
alert(Number(dd)); // 10 valueOf
alert(dd== '10'); // true valueOf

通過以上幾個例子我們發(fā)現(xiàn):只重寫了toString,對象轉換時會無視valueOf的存在來進行轉換。但是,如果只重寫了valueOf方法,在要轉換為字符串的時候會優(yōu)先考慮toString方法并會在原型鏈中去找。在不能調(diào)用toString的情況下,只能調(diào)用valueOf 方法了。

望大家多多提意見在下方評論哈!

?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容