在javascript中将`Object.assign`指定给一个基元类型时会发生什么?

在javascript中将`Object.assign`指定给一个基元类型时会发生什么?,javascript,Javascript,我发现您可以调用javascript中的字符串或数字类型上的Object.assign,以获得某种“增强”原语类型 // closure used to create object for simplicity function makeObj() { let value = 6; let enhancedValue = Object.assign(value, { set: () => 'from the set method' })

我发现您可以调用javascript中的
字符串
数字
类型上的
Object.assign
,以获得某种“增强”原语类型

// closure used to create object for simplicity
function makeObj() {

    let value = 6;

    let enhancedValue = Object.assign(value, {
        set: () => 'from the set method'
    })

    return {
        someValue: enhancedValue
    };
}

let myObj = makeObj();

// output is from nodejs

console.log(myObj.someValue); // accessing
// outputs: `{ [Number: 6] set: [Function: set] }`
console.log(myObj.someValue + 3); // using
// outputs: `9`
console.log(myObj.someValue.set()) // using method
// outputs: `from the set method`

所以我的问题是:这是什么类型的?是否有任何规范定义此行为?有什么理由不这样做吗?你能解释一下这里发生了什么吗?

在JavaScript中,几乎所有的基元类型都有一个等价的对象类型。因此,
“x”
是一个字符串原语,
新字符串(“x”)
是一个字符串对象。类似地,还有数字原语和
数字
对象,以及布尔原语和
布尔
对象等

的第一步是获取第一个参数并对其使用,这将执行原语到对象的步骤。从那时起,它使用ToObject返回的对象。(如果ToObject已经是对象,则只返回其参数。)


该对象是
assign
最终返回的对象。

所有基本类型都可以“装箱”到对象中。有一个
Number
prototype、
String
prototype等等。基本上是一个
新的Number(6)
对象和额外的properties@T.J.Crowder,谢谢你的回答,它解释了很多!我的最后一个问题是:是否有任何理由不向字符串/数字等添加方法?这是一种糟糕的做法吗?@Bergi:Gah,出于某种原因,我的头在别处,在ES5中思考。我本想回去解释一下这两者的区别,但它毕竟是相切的,所以我就把它删掉了。@RicoKahler:你会发现关于这一点的两个学派,都有忠实的、直言不讳的、理性的追随者:“不!没有理由,去做吧,这毕竟是原语的重点。小心命名冲突。”还有“是的,有;你将不可避免地与做同样事情的其他人发生冲突。而且,即使您没有与另一个执行扩展的脚本发生冲突,您也可能最终与未来的标准发生命名冲突。”两个阵营至少可以在一件事上达成一致:永远不要向内置原型添加可枚举属性。:-@RicoKahler:是的。如果您这样做,我建议使用
Object.defineProperty
(仅适用于一个)或
Object.defineProperties
(对于多个)。可枚举的
标志(与属性描述符中的所有标志一样)的默认值为
false
@RicoKahler No,T.J.Crowder只谈到本机原型(如
Number.prototype
)这就是所有的原语。如果你要创建你自己的对象实例,你可以用它们做任何你想做的事情(包括可枚举属性)。虽然装箱的原语很奇怪,通常建议不要使用它们,而是创建一个合适的类来代表你需要的。