JavaScript对象和方法算术运算或输出之valueOf和toString优先级

来源:互联网 发布:浏览器注入js脚本 编辑:程序博客网 时间:2024/06/05 20:12

直接输出对象名先toString再valueOf

var obj = {    toString: function() {        console.log('调用了 obj.toString');        return {};    },    valueOf: function() {        console.log('调用了 obj.valueOf')        return '110';    }}alert(obj);// 调用了 obj.toString// 调用了 obj.valueOf// 弹出110

从上面代码可看出输出obj时,先调用其toString方法,若toString返回原始值就直接返回,否则继续调用valueOf方法。

对象参与运算先valueOf再toString

var obj = {    toString: function() {        console.log('调用了 obj.toString');        return 123;    },    valueOf: function() {        console.log('调用了 obj.valueOf')        return {};    }}alert(obj+1);
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

若toString和valueOf都返回对象则程序报错

对象与数值运算转原始值先valueOf再toString

var obj = {    valueOf: function() {        console.log('调用 valueOf');        return 5;    }}console.log(obj + 1);// 调用 valueOf// 6var obj = {    valueOf: function() {        console.log('调用 valueOf');        return {};    },    toString: function() {        console.log('调用 toString');        return 10;    }}console.log(obj + 1);// 调用 valueOf// 调用 toString// 11var 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

方法名运算先valueOf,若valueOf返回对象再toString

function test() {    var a = 1;    console.log(1);}test;// 这里打印函数内容,即调用了test.valueOf()test.valueOf = function() {    console.log('调用 valueOf 方法');    return 2;} test;// 输出如下:// 调用 valueOf 方法// 2

添加toString方法并将valueOf返回对象

test.valueOf = function() {    console.log('调用 valueOf 方法');    return {};}test.toString= function() {    console.log('调用 toString 方法');    return 3;}test;// 输出如下:// 调用 valueOf 方法// 调用 toString 方法// 3

若将其valueOf和toString都返回对象,程序不会报错

test.valueOf = function() {    console.log('调用 valueOf 方法');    return {};}test.toString= function() {    console.log('调用 toString 方法');    return {};}test;//调用 valueOf 方法//调用 toString 方法//ƒ #<Function>

题目

add(1)(2) // 3add(1, 2, 3)(10) // 16add(1)(2)(3)(4)(5) // 15

实现:

function add() {    var args1 = Array.prototype.slice.call(arguments);    var fn = function () {        var args2 = Array.prototype.slice.call(arguments);        return add.apply(null,args2.concat(args1));    };    fn.toString = function () {      return  args1.reduce(function (a, b) {            return a * b;        });    };   <!-- fn.valueOf = function () {        return  args1.reduce(function (a, b) {            return a + b;        });    };-->    return fn;}

其中,valueOf和toString,哪个先被改写优先调用谁,同时出现,调用valueOf

构造函数实例算术运算先原型上的valueOf,输出调用toString

class Test {    valueOf () {        console.log('调用 valueOf 方法');        return 'v';    }    toString() {        console.log('调用 toString 方法');        return 's';    }}var T1 = new Test();

测试:

T1+1VM20301:3 调用 valueOf 方法"v1"`${T1}`VM20301:7 调用 toString 方法"s"