toString()和valueOf()函数调用和优先级

最近水群的时候看见了一个题目:

add(2)(3)(4);

简单了说就是链式调用,链式调用的方法有很多,jQuery的,underscore的和lodash这三个库采用了不同的方式。而上面这个就简单多了:

function add(x) { 

  var sum = x; 

  var tmp = function (y) {  

  sum = sum + y; 

    return tmp;  

  };    

tmp.toString = function () {   

   return sum;    

}; 

   return tmp;

}

这边只是使用了输出或者是运算的时候类型的转换。

JavaScript中几乎所有的对象都继承了toString和valueOf这两个方法:

valueOf()会把数据类型转换成原始类型

toString()会把数据类型转换成string类型

需要注意的是,这两个方法在不同使用场景会有不同的优先级:

正常情况下,优先调用toString()

有运算操作符的情况下valueOf()的优先级高于toString()

当调用valueOf()方法无法运算后还是会再调用toString()方法

我们可以改写这两个方法测试优先级:

var n = { 

   toString: function () { 

       return 1 

   }, 

   valueOf: function () {  

      return 2 

   }

}

var obj = {1: 1, 2: 2};

console.log(+n);//1

console.log(obj[n]);//2

除了上面三个方法之外,还是有一些会比较特殊,比如Date,应该还有很多我还不知道的优先级:

var date=new Date();

date.valueOf = function(){  

  return '1000'

}

console.log(+date);

大概知道这两个方法之后,回归这个函数:

function add(x) {  

  var sum = x; 

   var tmp = function (y) { 

    sum = sum + y; 

     return tmp;  

  };

  tmp.toString = function () { 

   return sum;   

 };

  return tmp;

}

调用:add(5)(3)(2)

其实add(5)是一个函数

console.log(typeof add(5));//function

是这个函数:

function (y) {  

  sum = sum + y; 

   return tmp;

};

因为闭包的原因,tmp和sum都被存起来了。所以我们可以链式调用。

add(5)(2)(3);

当我们执行完毕,想要运算或者是输出的时候,就会执行toString方法。

tmp.toString = function () {  

  console.log('toString')  

  return sum;

};

然后执行输出或者是运算:

add(5)(2) + add(5)(3);//toString toString

但是不同浏览器会有不同的结果,火狐上面:

console.log(add(5)(4));


不进行运算是不会调用toString的。

Coding 个人笔记

猜你喜欢

转载自blog.csdn.net/wade3po/article/details/88988287