数值之间的转换

首先我们要学好一个东西, 那么就要知道他底层是怎么运行的
比如说 我们用对象转数字

1.先去看我们的对向上有没有Symbol.toPrimitive方法,如果有这个方法就先执行这个方法
2.如果没有Symbol.toPrimitive属性,那么就执行valueOf 方法,获取它的原始值
3.然后再执行 toString 方法把他变成字符串

比如说
在这里插入图片描述
接下来我们看一到 很金典的面试题

let a = ?;
if(a == 1 & a==2 & a == 3) {
	console.log("ok");
}

很明显 这个是考察我们的隐式转化的问题,对象转数字

== 会存在隐式转化,转化成相同类型的值去比较, === 则不会隐式转化,
所以写代码 最好是写 ===

答案如下

// 方案一
let a = {
   i: 0,
    [Symbol.toPrimitive] ()  {
		return ++this.i;
   }
};
// 方案二
let a = [1,2,3];
a.toString = a.shift;
这样子 同样也可以打印出ok, shift是每次拿到第一个值,并返回这个数字

//方案三 通过数据劫持的方法
var i = 0;
Object.defineProperty(window, "a", {
	get() {
   			return ++i;
    }
})
// 只要这里一用到a 就会被截取, 然会做返回处理
if(a == 1 & a==2 & a == 3) {
	console.log("ok");
}
// 方案四 我们学过Vue3.0 就知道 响应式是通过 Proxy 去做的拦截,所以说可以通过Proxy去做 方法也跟上面方案三差不多

这个样子写 答案就是可以打印出ok了, 我们前面也说了 顺序是
Symbol.toPrimitive -> valueOf -> toString 你重写这三个方法中哪一个都可以

说到这里了 我就简单的提一下 +
+有两个作用
1.字符串拼接
只要是左边跟右边其中有一个是字符串,那么就是字符串拼接
比如:

const result = 10 + 12.5 + "a" +  [] + 10 + 30;
//解释: 10跟12.5 都是数字,所以变成了22.5 然后再加上a 就变成了字符串, []转字符串就是""
答案是 '22.5a1030'

2.隐式转化成数字
+new Date()
Date 就有这个属性 Symbol.toPrimitive
在这里插入图片描述

结果就是时间搓

我们来看一下 parseInt的用法
parseInt(value, redix)
第一个参数是值,必须是字符串,不然可能出现其他的问题
第二个是进制, 返回值 2进制到36进制
第二个参数不写,默认是10进制

parseInt("013")   // 13
parseInt("01554sdfs")    // 1554
parseInt(013)     // 11

parseInt(“01554sdfs”) 为什么是 1554, 原理是他会一个一个的去找,
0 1 5 5 4 遇到s了 判断是不规则数字,那么就不会再继续往下走了,那么就会把
前面的 01554 做10进制的转换 就变成了 1554
为什么会出现上面的这个结果, 如果第一个参数是数字不是字符串, 并且是以 0 开头的话就会默认以8进制来处理, 所以结果是 11

那我们来看下面这到面试题

let arr = [27.2,  0, "0013", "14px", 123];
arr = arr.map(parseInt);
console.log(arr);

结果是这个, 卧槽, 怎么是这些值, 是不是头都大了
在这里插入图片描述
下面来给你解释为什么
map是要执行完成了,并且会把最新的那个值给覆盖原来的值,返回一个新的数组

arr.map(parseInt);
其实就是
arr.map((item, index) => {
	return parseInt(item, index)
});
那么第一项 如果parseInt第二项填的是0 那么他的作用跟10进制是一样的
parseInt(27.2, 0)   // 结果是27
parseInt(0, 1)       // 因为我们的进制范围是 2~36 所以1进制是不符合的 就返回了NaN
parseInt( "0013", 2) // 0 0 1  (3是不符合2进制的, 所以舍弃)001的2进制 结果是 1
parseInt( "14px", 3)  // 同样 4也不满足三进制 就只有1 的三进制 结果就是1
parseInt( 123, 4)   // 都满足 1*4^2 + 2*4^1 + 3*4^0 结果就是 16 + 8 + 3 = 27

上面就是这个题的答案

那我们老看一下,浮点型的问题

0.1 + 0.2 == 0.3 ?
答案是什么?
在这里插入图片描述
结果是 false? 为什么, 这个就是扯到我们浮点数 丢失精度的问题了

0.1 + 0.2
在这里插入图片描述

请看下面这个图, 浮点数 存放的是2进制, 所以他会一直 *2 , 如果大于1了就放在左边,然后计算机是64位操作系统, 所以只会保存64个字节,然后多余循环的就省去了,这个就存在精度丢失的问题了
在这里插入图片描述
如果我们想解决 精度丢失的问题, 那么就把他先扩大变成 整数, 然后再除以放大的倍数就得到我们的结果了

// 这个是 得到放大多少的倍数
const pow = function pow(target) {
    const [, result] = target.split(target);
    return Math.pow(10, result.length)
}

const plus = function plus(val1, val2) {
    val1 +="";
    val2 +="";
    if(isNaN(val1) || isNaN(val2))  return NaN;
    // 这个是为了拿到最大的那个商职
    let max = Math.max(pow(val1), pow(val2));
    return (val1 * max + val2 * max) / max;
}

console.log(plus(0.51, 0.2546));
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值