Undefined类型表示未定义,它的类型只有一个值为undefined。任何变量在赋值前都是undefined类型,值为undefined。但是JS中undefined是一个变量,并非是一个关键字,为了避免无意中的篡改,使用void 0来获取undefined值。
undefined和null有一定的表意差别,null表示“定义了但是为空”,它只一个值为null,并且是JS关键字,可以放心使用。
非整数的Number类型无法使用 == 或 === 来比较,有一段著名的代码
console.log(0.1 + 0.2 == 0.3);
输出结果是false,说明两边不等,这是浮点运算的特点,浮点数运算的精度问题导致等式左右并不是严格相等,而是相差了个微小的值。
正确的比较方法是使用JS提供的最小精度值:
console.log(Math.abs(0.1 + 0.2 -0.3) <= Number.EPSILON);
检查等式左右两边差的绝对值是否小于最小精度值,才是正确的比较浮点数的方法。
因为 JS 是弱类型语言,所以类型转换发生非常频繁,大部分我们熟悉的运算都会先进行类型转换。大部分类型转换符合人类的直觉,但是如果我们不去理解类型转换的严格定义,很容易造成一些代码中的判断失误。其中最为臭名昭著的是 JS 中的“ == ”运算,因为试图实现跨类型的比较,它的规则太过复杂。很多实践中推荐禁止使用“ ==”,而要求程序员进行显式地类型转换后,用 === 比较。
parseInt 和 parseFloat 是很常用的类型转换的方法。在不传入第二个参数的情况下,parseInt 只支持 16 进制前缀“0x”,而且会忽略非数字字符,也不支持科学计数法。在一些古老的浏览器环境中,parseInt 还支持 0 开头的数字作为 8 进制前缀,这是很多错误的来源。所以在任何环境下,都建议传入 parseInt 的第二个参数,而 parseFloat 则直接把原字符串作为十进制来解析,它不会引入任何的其他进制。
多数情况下,Number 是比 parseInt 和 parseFloat 更好的选择。
每一种基本类型 Number、String、Boolean、Symbol 在对象中都有对应的类,所谓装箱转换,正是把基本类型转换为对应的对象,它是类型转换中一种相当重要的种类。全局的 Symbol 函数无法使用 new 来调用,但我们仍可以利用装箱机制来得到一个 Symbol 对象,我们可以利用一个函数的 call 方法来强迫产生装箱。我们定义一个函数,函数里面只有 return this,然后我们调用函数的 call 方法到一个 Symbol 类型的值上,这样就会产生一个 symbolObject。
我们可以用 console.log 看一下这个东西的 type of,它的值是 object,我们使用 symbolObject instanceof 可以看到,它是 Symbol 这个类的实例,我们找它的 constructor 也是等于 Symbol 的,所以我们无论哪个角度看,它都是 Symbol 装箱过的对象:
var symbolObject = (function(){
return this;
}).call(Symbol("a"));
console.log(typeof symbolObject); //object
console.log(symbolObject instanceof Symbol); //true
console.log(symbolObject.constructor == Symbol); //true
装箱机制会频繁产生临时对象,在一些对性能要求较高的场景下,我们应该尽量避免对基本类型做装箱转换。
使用内置的Object函数,可以在JS代码中显式的调用装箱能力。
var symbolObject = Object((Symbol("a"));
console.log(typeof symbolObject); //object
console.log(symbolObject instanceof Symbol); //true
console.log(symbolObject.constructor == Symbol); //true
每一类装箱对象皆有私有的Class属性,这些属性可以用Object.protoype.toString获取:
var symbolObject = Object((Symbol("a"));
console.log(Object.prototype.toString.call(symbolObject)); //[object Symbol]
JS中,没有方法可以更改私有的Class属性,因此Object.prototype.toString是可以准确识别对象对应的基本类型的方法,它比instanceof更加准确。
但需要注意的是,call 本身会产生装箱操作,所以需要配合typeof来区分基本类型还是对象类型。
JS标准中,规定了ToPrimitive函数,它是对象类型到基本类型的转换。(即拆线转换)
对象到String和Number的转换都遵循“先拆箱再转换”的规则。通过拆箱转换,把对象编程基本类型,再从从基本类型转换成对应的String或者Number。
拆箱转换会尝试调用valueOf和toString来获得拆箱后的基本类型。如果valueOf和toString都不存在。或者没有返回基本类型,则会产生类型错误的提示TypeError。
var o = {
valueOf : () => {console.log("valueOf"); return {}},
toString : () => {console.log("toString"); return {}}
}
o * 2
// valueOf
// toString
// TypeError
我们定义了一个对象 o,o 有 valueOf 和 toString 两个方法,这两个方法都返回一个对象,然后我们进行 o * 2 这个运算的时候,你会看见先执行了 valueOf,接下来是 toString,最后抛出了一个 TypeError,这就说明了这个拆箱转换失败了。
到 String 的拆箱转换会优先调用 toString。我们把刚才的运算从 o*2 换成 o + “”,那么你会看到调用顺序就变了。
var o = {
valueOf : () => {console.log("valueOf"); return {}},
toString : () => {console.log("toString"); return {}}
}
o + ""
// toString
// valueOf
// TypeError
在JavaScript中存在这样两种原始类型:Null与Undefined。这两种类型常常会使JavaScript的开发人员产生疑惑,在什么时候是Null,什么时候又是Undefined?Undefined类型只有一个值,即undefined。当声明的变量还未被初始化时,变量的默认值为undefined。
主要介绍了JS中检测数据类型的几种方式,typeof运算符用于判断对象的类型,但是对于一些创建的对象,它们都会返回\'object\',有时我们需要判断该实例是否为某个对象的实例,那么这个时候需要用到instanceof运算符
对于object和number、string、boolean之间的转换关系,ToPrimitive是指转换为js内部的原始值,如果是非原始值则转为原始值,调用valueOf()和toString()来实现。
近在做项目代码重构,其中有一个要求是为代码添加智能提示和类型检查。智能提示,英文为 IntelliSense,能为开发者提供代码智能补全、悬浮提示、跳转定义等功能,帮助其正确并且快速完成编码。
基本类型:按值访问,可以操作保存在变量中实际的值;引用类型数据存在堆内存,而引用存在栈区,也就是说引用类型同时保存在栈区和堆区,关于==的执行机制,ECMASript有规范,因为==前后的值交换顺序,返回的值也是一样的,所以在此对规范做出如下总结
JavaScript 是一种弱类型或者说动态类型语言。所以你不用提前声明变量的类型,在程序运行时,类型会被自动确定,你也可以使用同一个变量保存不同类型的数据。
js的值传递和引用(地址)传递:js的5种基本数据类型 number,string,null,undefined,boolean 在赋值传递时是值传递,js的引用数据类型(object,array,function)进行引用传递,其实底层都是对象。
JS中所有的值都可以转换成布尔类型 使用Boolean()或者 !!(两个感叹号),JS中所有的值都可以转换成数字类型,使用Number()或+。数字类型转换场景目的只有一个,用于计算,将后台传递的数据,从字符串转换为数字并参与计算
众所周知,JS在很多情况下会进行强制类型转换,其中,最常见两种是:1.使用非严格相等进行比较,对==左边的值进行类型转换2.在if判断时,括号内的值进行类型转换,转化为布尔值
根据规范,对象的属性键只能是 String 类型或者 Symbol 类型。不是 Number,也不是 Boolean,只有 String 或 Symbol 这两种类型。到目前为止,我们只见过 String。现在我们来看看 Symbol 能给我们带来什么好处。
内容以共享、参考、研究为目的,不存在任何商业目的。其版权属原作者所有,如有侵权或违规,请与小编联系!情况属实本人将予以删除!