背景介绍
我从事前端工作只能有短短的一年,工作要求使我接触到了前端这个领域。起初对于前端的理解就是html、css、js,但是随着对前端这个领域的不断了解,我发现前端远不止这些。虽然目前我已经能够根据需求写出不错的前端代码,但是我所掌握度前端知识实际上过于零散,基础知识的欠缺限制了我解决问题的思路。重新系统的学习一遍前端知识对我来说是非常必要的。此文章主要用来记录学习中的问题,希望能帮助到同我一样的前端学习者。
undefined
undefined在JavaScript中是一个变量而非一个关键字,这其实是JavaScript的设计失误之一。在某些浏览器中允许你重写undefined,建议使用void 0来获取undefined值。
0.1+0.2===0.3???
根据双精度浮点数的定义Number 类型中有效的整数范围是-0x1fffffffffffff 至 0x1fffffffffffff,也就说JavaScript无法表示此范围之外的整数。对于64位浮点数(double)来说,大于1的最小浮点数相当于二进制的1.00..001小数点后面有连续51个零。这个值减去1 之后,就等于2的-52 次方。所以非整数的Number类型数字无法使用==或者===进行比较。正确的比较方法为:Math.abs(0.1 + 0.2 - 0.3) <= Number.EPSILON
“类”===“类型”???
由于C++、java等语言中每一个类都有一个类型一一对应,所以很多人将JavaScript中的“类”与类型混淆。实际上JavaScript中无法自定义类型。3与new Number(3)是完全不同的值,一个是number类型,一个是对象类型。
Number、Boolean、String跟new配合可以生成对象,直接调用则是强制类型转换。Symbol函数比较特殊无法使用new。
装箱操作
那为什么number类型数据可以调用Number对象类型中定义的方法?实际上.运算符进行了一个封箱操作,根据基础数据类型构造一个临时对象类型,使得我们可以在基础数据类型之上调用对象方法。频繁的装箱操作会产生大量临时对象,所以在要求高性能的场景应尽量避免使用装箱操作。
拆箱转换
JavaScript中规定了ToPrimitive函数它是对象到基本类型的转换
var o = {
valueOf : () => {console.log("valueOf"); return {}},
toString : () => {console.log("toString"); return {}}
}
o * 2
// valueOf
// toString
// TypeError
类型转换的内部实现是通过ToPrimitive ( input [ , PreferredType ] )方法进行转换的,这个方法的作用就是将input转换成一个非对象类型。参数preferredType是可选的,它的作用是,指出了input被期待转成的类型。如果不传preferredType进来,默认的是'number'。如果preferredType的值是"string",那就先执行"toString", 后执行"valueOf"。否则,先执行"valueOf", 后执行"toString"。由此可见,"toString", "valueOf"的执行顺序,取决于preferred的值。