是值是原始的还是盒装的

Ray*_*nos 16 javascript boxing typeof

可以typeof用来确定值是原始的还是盒装的.

考虑:

typeof "foo"; // "string"
typeof new String("foo"); // "object"
Run Code Online (Sandbox Code Playgroud)

结合Object.prototype.toString我们可以定义以下两个函数

var toString = Object.prototype.toString;

var is_primitive_string = function(s) {
  return toString.call(s) === "[object String]" && typeof s === "string";
};

var is_boxed_string = function(s) {
  return toString.call(s) === "[object String]" && typeof s === "object";
};
Run Code Online (Sandbox Code Playgroud)

是否有任何使用情况下这两个功能呢?(或者类似的功能Number,Boolean等等).

这个问题背后的概念来自TJCrowder的以下评论.

我们是否应该关心我们拥有的价值是原始的还是盒装的?

T.J*_*der 7

我说几乎没有意义,你几乎不关心你是在处理string原始还是String对象.

有边缘情况.例如,String对象是实际对象,您可以向其添加属性.这可以让你做这样的事情:

function test(arg) {
    arg.foo = "bar";
}
Run Code Online (Sandbox Code Playgroud)

如果调用代码传递一个string 原语:

var s1 = "str";
test(s1);
Run Code Online (Sandbox Code Playgroud)

... arg被提升为一个String对象并获取一个属性,但返回String后该对象不被任何东西使用test.

相反,如果调用代码传入一个String 对象:

var s2 = new String("str");
test(s2);
Run Code Online (Sandbox Code Playgroud)

...然后将属性添加到该对象,调用代码可以看到它.考虑(实时复制):

var s1, s2;

s1 = "str";

display("[Before] typeof s1.foo = " + typeof s1.foo);
test(s1);
display("[After] typeof s1.foo = " + typeof s1.foo);

s2 = new String("str");

display("[Before] typeof s2.foo = " + typeof s2.foo);
test(s2);
display("[After] typeof s2.foo = " + typeof s2.foo);

function test(arg) {
  arg.foo = "bar";
}
Run Code Online (Sandbox Code Playgroud)

输出:

[Before] typeof s1.foo = undefined
[After] typeof s1.foo = undefined
[Before] typeof s2.foo = undefined
[After] typeof s2.foo = string

请注意,这s2.foo是一个字符串,但s1.foo不是(因为s1是一个字符串原语,当我们将其提升时创建的对象test与调用代码无关).

这有什么用例吗?不知道.如果是这样的话,我会说这将是一个非常前卫的边缘案例.