基本包装类型和基本类型的那点事

403 2 年前
我们都知道javascript中一些基本类型(boolean,string,number)都有自己的构造函数,我们称之为基本包装类型,但是基本包装类型和基本类型不是一回事。

我们都知道javascript中一些基本类型(boolean,string,number)都有自己的构造函数,我们称之为基本包装类型,但是基本包装类型和基本类型不是一回事。

以boolean类型为例,在大多数代码中,我们使用boolean值像这样:

var primitiveTrue = true;
var primitiveFalse = false;

当然,还有Boolean函数,它可以被用作一个布尔函数,它返回一个布尔值。

var functionTrue = Boolean(true);
var functionFalse = Boolean(false);

同时Boolean函数也可以被用作一个构造函数,使用new关键字:

var constructorTrue = new Boolean(true);
var constructorFalse = new Boolean(false);

奇怪是是Boolean被用作一个构造函数时,它返回的不是一个boolean值,而是一个对象:

// Outputs: true
console.log(primitiveTrue);

// Outputs: true
console.log(functionTrue);

// Outputs: Boolean {}
console.log(constructorTrue);

//Outputs boolean
console.log(typeof primitiveTrue);

// Outputs: object
console.log(typeof constructorTrue);

事实证明,使用布尔构造函数是相当危险的。为什么呢?JavaScript有关强制类型转换是想当激进的。如果您尝试把一个字符串和一个数字相加,这个数字将被强制转换为字符串。

// Outputs: "22"
console.log("2" + 2);

同样,如果您在if语句中尝试使用一个对象,对象将被强制转换为true。

// Outputs: "Objects coerce to true."
if ({}) { console.log("Objects coerce to true."); }

而且,由于Boolean对象是一个对象,它也将强制为true,即使它的值是false。

// Outputs: "My false Boolean object is truthy!"
if (constructorFalse) {
    console.log("My false Boolean object is truthy!");
} else {
    console.log("My false Boolean object is falsy!");
}

那么我们确实需要布尔值的时候该怎么办呢?我们可以使用valueOf()方法:

// Outputs: "The value of my false Boolean object is falsy!"
if (constructorFalse.valueOf()) {
    console.log("The value of my false Boolean object is truthy!");
} else {
    console.log("The value of my false Boolean object is falsy!");
}

由于存在这样的现象,所以我们平时定义boolean、number、string值时,建议使用字面量的形式定义。同时在一些代码检测工具(jshint/jsLint)中,使用构造函数初始化时,会报错。

最后在你强制转换一种类型为boolean类型的时候,建议使用Boolean作为一个普通函数,或者进行两次取非操作。

// Two approaches to coercing 0 into false
var byFunction = Boolean(0);
var byNotNot = !!0;
分类栏目
© 2018邮箱:11407215#qq.comGitHub沪ICP备12039518号-6