gpt4 book ai didi

javascript - JavaScript 对象和原始类型有什么区别?

转载 作者:可可西里 更新时间:2023-11-01 02:40:24 24 4
gpt4 key购买 nike

Stoyan Stefanov 在他的优秀著作“面向对象的 JavaScript”中说:

Any value that doesn't belong to one of the five primitive types listed above is an object.

对于五种基本类型,他表示 NumberStringBooleanUndefinedNull。然而,在 Google Chrome 控制台中,数字似乎根本不是原始类型(与 C 原始类型(如 int)相比)。看起来原始数字有方法:

var a = 2.2;
console.log(a.toFixed()); // logs "2"

因此我假设我可以像处理对象一样处理数字,所以我尝试为它分配一个属性:

var a = 2;
a.foo = 'bar';
console.log(a.foo); // logs undefined

我不明白这种行为。如果数字有一个方法,它应该表现得像对象,不是吗?它甚至有一个原型(prototype):

Number.prototype.foo = 'bar';
var a = 2;
console.log(a.foo); // logs 'bar'

那么这背后的魔法是什么? JavaScript 如何处理对象与原始 类型?我宁愿不使用原始这个词,而是用简单对象代替它。在我看来,这些对象无法使用新属性进行扩展,但是它们是通过构造函数构建的,并且还具有可以像普通对象一样进行扩展的原型(prototype)。

最佳答案

[...] It looks like the primitive number has methods

原始的,实际上并没有自己的属性。它被强制到一个对象,以便能够访问“它的”属性。强制对象在被调用方法之外不可访问*(在严格模式下,甚至在方法内部)*。因此,引用的变量始终是原始变量。

考虑这个简单的例子:

Number.prototype.myTypeInAMethod = function () {
console.log (typeof this.valueOf ()) //"number" => The primitive is wrapped in an object.
return typeof this;
}

var num = 123;
typeof num; //number
num.myTypeInAMethod () //object

旁注:在 ES5 的严格模式下,this 将是原始类型,类型将是数字

由于变量 num 是原始变量,您可以为其赋值。

num.foo = "bar";
num.foo //undefined

如果您改为通过其对象构造函数创建一个数字(或字符串),则其类型确实是一个对象。通过添加属性进行快速检查表明它实际上可以被分配。

var objNum = new Number(123);
typeof objNum ; //"object"
objNum.foo = "bar";
objNum.foo //"bar"

So what is the magic behind this? How JavaScript treats objects versus primitive types?

此过程在 ES5 §8.7.1 中有所描述获取值(value)

对于一个对象:

  • 如果 Type(V) 不是 Reference,则返回 V
  • 设 base 为调用 GetBase(V) 的结果。
  • 如果IsUnresolvableReference(V),抛出一个ReferenceError异常。
  • 如果 IsPropertyReference(V),则
    • 如果HasPrimitiveBase(V)false,则令getbase< 的[[Get]] 内部方法/em>,否则让 get 成为下面定义的特殊 [[Get]] 内部方法。
    • 返回使用 base 作为其 this 值调用 get 内部方法并传递 GetReferencedName(V) 用于参数。
  • 否则,base 必须是环境记录。
    • 返回调用 GetBindingValue 的结果(参见 10.2.1 ) base 传递 GetReferencedName(V) 的具体方法IsStrictReference(V) 作为参数。

对于原语:

The following [[Get]] internal method is used by GetValue when V is a property reference[1] with a primitive base value. It is called using base as its this value and with property P as its argument. The following steps are taken:

  • OToObject(base)
  • desc 是调用 O 的 [[GetProperty]] 内部方法并使用属性名称 P 的结果。
  • 如果 descundefined,返回undefined
  • 如果 IsDataDescriptor(desc)true,则返回 desc。[[Value]]。
  • 否则,IsAccessorDescriptor(desc) 必须为 true 因此,让 getterdesc。[[Get ]].
  • 如果 getterundefined,返回undefined
  • 返回调用 getter 的 [[Call]] 内部方法的结果,提供 base 作为 this 值并且不提供任何参数。

<子>注意 在上述方法之外无法访问在步骤 1 中创建的对象。实现可能会选择避免实际创建对象。使用此内部方法的此类实际属性访问可以产生可见效果的唯一情况是调用访问器函数时。

[1] IsPropertyReference(V)。如果基值是对象或 HasPrimitiveBase(V)true,则返回 true;否则返回 false

关于javascript - JavaScript 对象和原始类型有什么区别?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21933120/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com