3

一个非常简单的问题,是否有过在 javascript 中使用原始数据类型更可取的情况,我特别被原始布尔值困扰,请考虑以下代码

var bool = new Boolean(false);
if (bool){
    alert(bool);
}

它会alert,但你会得到false,这有点令人困惑(false!= falsy)。

那么使用原始数据类型,尤其是原始布尔值有什么意义吗?

4

3 回答 3

8

这些不是原语。原语如100, "foobar", false:

> typeof false
"boolean"
> typeof new Boolean(false)
"object"

new Boolean(or Numberor String) 是一个对象,它遵循对象,而不是原始的比较规则,布尔转换等。这些对象对于 JS 程序员来说确实几乎没有用处(与在内部使用它们的 JS 引擎相反)。

请注意,虽然很少需要使用Boolean和朋友来构造对象(如x = new Boolean(...)),但这些函数本身有时很有用。例如,以下很好的习惯用法会从数组中删除所有虚假值:

ary = ary.filter(Boolean)
于 2013-11-14T14:03:18.453 回答
3

原始值非常有用(例如原始值:true、false、null、1、2 等)。您在问题中谈论的是围绕它们的对象包装器。

对象包装器很有用,因为它允许您添加要在它们上调用的函数。更重要的一件事是,当您在原始值上调用方法时,会在它们之上创建对象包装器,并在对象包装器上调用方法*。

示例 1:字符串

String.prototype.sayHello = function() {
  return this + ' says hello';
};

// calling a method on a string literal temporarily converts it to a String
console.log('John'.sayHello()); // 'John says hello'

示例 2:布尔值

var bool = new Boolean(false);
console.log(bool); // Boolean
console.log(bool.toString()); // 'false'
console.log(bool.valueOf()); // false

// How you can use it:
Boolean.prototype.toCaps = function() {
  return this.valueOf().toString().toUpperCase();
};

console.log(bool.toCaps()); // 'FALSE'

// calling a method on a boolean literal temporarily converts it to a Boolean
console.log(true.toCaps()); // 'TRUE'
console.log((1 === 1).toCaps()); // 'TRUE'

演示:http: //jsbin.com/apeGOve/1/edit

*) 每次在原始值上调用方法时都会创建不同的对象包装器:

String.prototype.getWrapper = function() { return this; };
String.prototype.setTest = function() { this.test = 'test' };
String.prototype.getTest = function() { return this.test; };

var str = '123';
console.log('Different wrappers each time',str.getWrapper() === str.getWrapper());

var wrapper = str.getWrapper();
wrapper.setTest();
console.log(wrapper.getTest());
console.log(str.getTest());
于 2013-11-14T14:15:46.513 回答
1

你的例子:

var bool = new Boolean(false);
if (bool){
    alert(bool);
}

并且您想知道为什么它会发出错误警报。

bool是变量,您在创建它时为其分配了一个值。所以,当你说if(bool)JavaScript 做了一些强制并测试是否bool是虚假的,它不是,所以条件块执行。现在您alert(bool)将尝试调用对象的 toString 方法并显示结果。boolean 对象的 toString 方法将 boolean 对象的值作为字符串返回,因此您会收到“false”一词的警报。

来吧,试试

var bool = new Boolean(false);
bool.toString = function () {
    return 'I need a banana';
}
if (bool){
    alert(bool);
}

你会得到完全不同的结果。

这给我们带来了另一个问题,即“为什么”您甚至会使用布尔构造函数:您可以将属性分配给布尔对象,而不能将属性分配给trueand false。例如,在使用可链接方法构建一些逻辑处理库时,您可能希望从布尔对象继承。

于 2013-11-14T21:16:18.393 回答