是否可以覆盖javaScript原始数据类型?

时间:2013-02-28 12:57:30

标签: javascript

问题是自我解释的。我知道可以扩展原始数据类型,例如string但是可以覆盖它吗?

这是一个在采访中提出的问题。

4 个答案:

答案 0 :(得分:2)

不,你不能覆盖任何东西。 EcmaScript defines the primitive types UndefinedNullBooleanNumberString;这些是内部的,无论你在做什么都将被使用(例如覆盖全局String构造函数)。 Type conversion和文字的评估不依赖于任何公共函数,而只使用这些内部类型和为它们指定的算法。

当然,如果某人使用String(myval)进行字符串强制而不是""+myval,则分配给全局String变量会对该代码产生影响。任何内部使用仍然指向“旧”功能。


如果您正在讨论基元类型的原型对象(使用as objects时),那么这些对象也不可覆盖。您可以扩展这些对象,但只要您分配给例如Number.prototype你刚刚丢失了对实际原始数字protype对象的引用。 The Number constructor的示例规范:

  

新构建的对象的[原型]设置为原始数字原型对象,Number.prototype的{​​strong>初始值({ {3}})

答案 1 :(得分:1)

是(编辑:差不多)。打开Javascript控制台(如果您使用的是Chrome,则输入F12)并输入

String = function(){alert('bang!')};

您可以在Javascript中覆盖(编辑:几乎)所有内容 - 甚至是window全局上下文! evil.js是一个使用此技巧来重写许多本机对象的库。

毋庸置疑,这非常危险。我执行了上面的String重新映射代码,自从写下来以来我已经造成了超过520个Javascript错误(我已经看过'爆炸'很多次警告)。本地对象随处可用,如果第三方代码以您不知道的方式依赖它们,则不应修改它们。这是Prototype.js失去知名度的原因之一 - 因为它对原生对象的扩展通常会违背其他代码的期望。

编辑:正如Bergianswer中所指出的那样,绝对错误地断言所有内容都可以被覆盖。编辑内联。

答案 2 :(得分:0)

可能是这样,但你必须始终没有副作用。没有好的做法。

function Array() {
  var obj = this;
  var ind = 0;
  var getNext = function(x) {
    obj[ind++] setter = getNext;
    if (x) alert("Data stolen from array: " + x.toString());
  };
  this[ind++] setter = getNext;
}
var a = ["private stuff"];
// alert("Data stolen from array: private stuff");

答案 3 :(得分:0)

  1. 您可以扩展原生类型的原型。

    String.prototype.moo = function() { 
       console.log( 'Moo!' ) 
    };
    'Cow says'.moo();
    >> "Moo!"
    
  2. 但是,除非覆盖对整个对象的引用,否则不能直接覆盖内置类型的构造函数:

    String = function() { 
       console.log( 'Custom function.' ) 
    };
    
    new String( 'Hello!' );
    >> "Custom function."
    >> String {} // now you've broken your website ;)
    
  3. ......但仍然:

    'Wat?!'
    >> "Wat?!" // you can still create strings by typing letters in quotes
    
  4. 所以......答案是“是但不是”。您可以使用原生类型(NumberDateString ...),但无法从头开始重新定义它们。它们是您正在使用的JS引擎的一部分(很可能是本机C ++代码),这带来了一些限制。