Javascript - 原语如何真正起作用

时间:2015-11-13 10:20:07

标签: javascript constructor primitive

我有以下代码:

String.prototype.isLengthGreaterThan = function(limit){
    return this.length > limit;
}

console.log("John".isLengthGreaterThan(3));

Number.prototype.isPositive = function(){
    return this > 0;
}

console.log(5.isPositive(3)); //error

第一个例子是工作,另一个没有。为什么呢?

根据我的理解,原语不是对象 - 尽管它们可以访问它们的函数构造函数的原型(NumberString等)。因此,您可以直接将方法添加到原型中。在上面的例子中,它在一个实例中不起作用。

我正在寻找“引擎盖下”的答案,以了解当你这样做时会发生什么,例如:

var a = 1;

如果它不是一个对象,它如何真正访问它的原型?

1 个答案:

答案 0 :(得分:2)

点的东西不是与原语有关,它只是写数字文字的语法。在一个数字中,.是小数点,而当然不是字符串的情况。要在文字编号上使用方法,您有两种选择:

  1. 的括号:

    console.log((5).isPositive(3));
    
  2. 两个点(是的,真的):

    console.log(5..isPositive(3));
    
  3. 在第二种情况下,它起作用,因为第一个点是小数点;这意味着后面的点不能是小数点,因此它是属性访问器运算符。

      

    如果它不是一个对象,它如何真正访问它的原型。

    当您执行权限访问时,它由JavaScript引擎自动提升为对象。在数字的情况下,它就像你打电话给new Number(5)或类似的一样。对于字符串,它就好像你调用new String("the string")一样。完成属性访问后,表达式完成后立即丢弃临时对象。当然,JavaScript引擎可以优化对象分配,但从概念上讲,会发生什么。

    概念上说:

    1. 我们(比方说)var n = 1;变量a包含原始数字值1

    2. 我们n.isPositive(3);使用Number.prototype.toFixed从中创建字符串。这是属性访问操作:

      1. 引擎评估左侧n,并获得结果1(原始数字);这是 base 它将用于属性访问操作。

      2. 引擎评估右侧(isPositive)以确定要查找的属性键(名称)。在这种情况下,它是一个文字,所以关键是字符串"isPositive"。这是属性访问操作的属性键。

      3. 发动机前往基地查找物业。由于我们拥有的基础是原语,因此JavaScript引擎将它(强制它)提升为等效的Number对象。

      4. 由于该对象没有"isPositive"属性,引擎会查看其原型Number.prototype并找到它;它是对函数的引用。

      5. 发生的各种事情并非真正密切相关,最终isPositive被调用this是从原始值1强制的对象。它发挥作用并产生其回报值。

      6. 由于临时对象不再被任何东西引用,因此它有资格进行垃圾回收。

    3. 发生这种情况的机制在规范中有点分散:

      • 属性访问器运算符的runtime semantics返回一个称为Reference规范类型的东西,它基本上是一个纯抽象的规范持有对象,将在以后进行评估。它说基数将是评估属性访问者左侧的结果,属性anme将是评估右侧的结果。

      • Reference类型上的GetValue operation,其中说明(步骤5)如果它是属性引用且基础是原始的,则它通过以下方式强制执行规范' ToObject操作。

      • ToObject,定义了执行此操作的规则。