Kotlin支持扩展现有类型。例如,我们can do this:
libprotoc.so
然而javascript this is an antipattern。
Kotlin是否回避了Javascript导致的问题?
答案 0 :(得分:7)
不,这不是反模式。在js中它是一个反模式,因为js是动态,因此更改原型会改变代码在运行时的工作方式,使其成为反模式。根据 in 运算符的工作方式以及基于您可以重写所有内容的事实,这也非常危险,因此更改原型会影响页面上的代码:< / p>
Number.prototype.toString = function(){
return "bullshit";
};
alert(""+12);
在kotlin中并非如此,因为kotlin是 static ,并且所有引用都是在编译时构建的。另外,你不能覆盖现有的方法,所以它根本没有危险。
答案 1 :(得分:2)
您无法将JS等原型语言与Kotlin进行比较。所有扩展程序都是静态解析的,不修改扩展类型(“receiver”)。这非常重要,可以使您的担心无效。请查看documentation以了解有关后台扩展程序(编译器)的更多信息。
在我看来,你需要谨慎扩展。不要允许Kotlin项目中的每个开发人员向随机类型添加新扩展。我认为项目必须定义某些规则来处理在现有类型上定义新函数/属性的过程,否则会很难读取外部代码。此外,应该有坚定的安排位置,以放置这些扩展。
答案 2 :(得分:1)
已有几种语言。 JavaScript的问题在于它的工作方式,如链接的答案中所述。
JavaScript有两种覆盖属性的方法。库可以很好地定义覆盖,但另一个覆盖它。从两个库中调用该函数,所有的地狱都会松动。
在我看来,这更像是一种类型系统和可见性问题。
答案 3 :(得分:1)
您应该编译此示例并查看生成的代码。一切都会变得清晰:
function replaceSpaces($receiver) {
return replace($receiver, 32, 95);
}
function foo(str) {
var formatted = replaceSpaces(str);
}
根本没有猴子补丁!扩展函数只是Kotlin中的一个语法糖。这只是将第一个参数传递给静态函数的另一种方式。
答案 4 :(得分:1)
不,这不好。 Kotlin允许扩展现有类型非常糟糕。
有了扩展,根本没有理由为此创建类层次结构甚至创建新的类定义。
Kotlin的创建者可能还只是使用了erlang,而不用去创建扩展名。
扩展名意味着您不再可以依靠类定义来保持不变。想像一下,人们一直在花时间寻找开发人员的“创造性”扩展,更不用说调试它们了。