深入js类型转换

之前写过js类型转换,https://blog.csdn.net/Y_G_G/article/details/78031510 是比较详细的规则,可能后面工作中用得多了,现在并不太注意这些。最近看了一篇文章,https://juejin.im/entry/58beb514128fe1006456df73 让我更深刻的认识了类型转换,尤其是对象类型转换.,以及看问题的本质。
个人觉得,记住具体的规则,去看红宝书就可以了。书上写的详细又具体。

问题引入

这篇文章 以一道面试题开始:

// 实现一个函数,运算结果可以满足如下预期结果:
add(1)(2) // 3
add(1, 2, 3)(10) // 16
add(1)(2)(3)(4)(5) // 15

给出的答案是:

function add () {
    var args = Array.prototype.slice.call(arguments);
    var fn = function () {
        var arg_fn = Array.prototype.slice.call(arguments);
        return add.apply(null , args.concat(arg_fn));
    }
    fn.valueOf = function () {
        return args.reduce(function (a, b) {
            return a + b;
        })
    }
    return fn;
}
问题分析

求和运算,链式调用,参数不定。

  • 猜测 会用到高阶函数 reduce 实现累加。
  • 调用add()的时候,如何既返回一个值又返回一个函数供后续调用?
// reduce进行累加
arr.reduce((a,b) => {
	return a+b;
})
function add() {
	var args = Array.prototype.slice.call(arguments);
	var fn = function() {
	}
	return fn;
}

Array.prototype.slice.call(arguments) 能将具有length属性的对象转成数组。
因为arguments并不是真正的数组对象,只是与数组类似,并没有slice这个方法,而Array.prototype.slice.call(arguments)可以理解成是让arguments转换成一个数组对象,让arguments具有slice()方法。直接写arguments.slice()会报错。

问题深入

function的转换

function test() {
    console.log(10);
}

test
// ƒ test() {
    console.log(10);
}
test() 
// 10

执行test和 test() 返回不同的结果。执行 test 会自行调用了函数的 valueOf 方法
下面重写 valueOf

test.valueOf = function() {
    console.log('调用 valueOf 方法');
    return 20;
}
test
// 调用 valueOf 方法
// 20
解决问题

让fn 拿到所有参数组成的数组,让数组做最后的累加。还是个闭包  ̄□ ̄

延伸 - 对象的转换

ToPrimitive:

  • 当对象类型需要被转为原始类型时,先查找对象的valueOf方法,如果valueOf方法返回原始类型的值,则ToPrimitive的结果就是这个值;
  • 如果valueOf不存在或者valueOf方法返回的不是原始类型的值,会调用对象的toString方法,会遵循对象的ToString规则,并toString的返回值作为ToPrimitive的结果。

简言之,一般对象先调用valueOf,有原始类型就返回,没有便继续找toString方法。(date 就先调toString)

var obj = {
    toString: function() {
        console.log('调用了 obj.toString');
        return 11;
    },
    valueOf: function() {
        console.log('调用了 obj.valueOf')
        return {};
    }
}

var  a = 88- obj
//调用了 obj.valueOf
//调用了 obj.toString
//77
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值