问题是自我解释的。我知道可以扩展原始数据类型,例如string
但是可以覆盖它吗?
这是一个在采访中提出的问题。
答案 0 :(得分:2)
不,你不能覆盖任何东西。 EcmaScript defines the primitive types Undefined
,Null
,Boolean
,Number
和String
;这些是内部的,无论你在做什么都将被使用(例如覆盖全局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失去知名度的原因之一 - 因为它对原生对象的扩展通常会违背其他代码的期望。
答案 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)
您可以扩展原生类型的原型。
String.prototype.moo = function() {
console.log( 'Moo!' )
};
'Cow says'.moo();
>> "Moo!"
但是,除非覆盖对整个对象的引用,否则不能直接覆盖内置类型的构造函数:
String = function() {
console.log( 'Custom function.' )
};
new String( 'Hello!' );
>> "Custom function."
>> String {} // now you've broken your website ;)
......但仍然:
'Wat?!'
>> "Wat?!" // you can still create strings by typing letters in quotes
所以......答案是“是但不是”。您可以使用原生类型(Number
,Date
,String
...),但无法从头开始重新定义它们。它们是您正在使用的JS引擎的一部分(很可能是本机C ++代码),这带来了一些限制。