Kotlin可以擴展現有的類型。例如,我們can do this:Kotlin是否允許擴展現有類型?
fun String.replaceSpaces(): String {
return this.replace(' ', '_')
}
val formatted = str.replaceSpaces()
但是JavaScript的this is an antipattern。
Kotlin是否迴避了在Javascript中導致的問題?
Kotlin可以擴展現有的類型。例如,我們can do this:Kotlin是否允許擴展現有類型?
fun String.replaceSpaces(): String {
return this.replace(' ', '_')
}
val formatted = str.replaceSpaces()
但是JavaScript的this is an antipattern。
Kotlin是否迴避了在Javascript中導致的問題?
不,這不是反模式。在js中它是一個反模式,因爲js是動態,因此更改原型會更改代碼的工作方式在運行時使其成爲反模式。這也是非常危險的基礎上如何在運營工作,並根據事實,你可以重寫一切,所以改變的原型就可以在網頁上的某個地方影響代碼:
Number.prototype.toString = function(){
return "bullshit";
};
alert(""+12);
在科特林這是不是因爲kotlin是靜態,並且所有參考都是在編譯時間。此外,你不能覆蓋現有的方法,所以它根本就沒有危險。
幾種語言已經有了。正如鏈接的答案中所述,JavaScript的問題是它的工作方式。
除了我的頭頂,JavaScript有一些重寫屬性的方法。一個庫可以很好地定義一個覆蓋,但另一個覆蓋它。從兩個庫中調用的函數,所有的地獄都打破了。
在我看來,這更多的是一個類型系統和可見性問題。
擴展歡迎:)
你不能比較JS和Kotlin這樣的原型語言。所有擴展名都是靜態解析的,並且不修改擴展類型(「接收者」)。這非常重要,並使您的擔心無效。請看documentation以瞭解更多關於在後臺使用擴展名(編譯器)發生的事情。
恕我直言,你需要謹慎擴展。不要讓Kotlin項目中的每個開發人員都爲隨機類型添加新的擴展。我認爲項目必須定義某些規則來處理在現有類型上定義新函數/屬性的過程,否則會難以閱讀外部代碼。此外,應該有堅定的安排位置放置這些擴展。
而不是在StackOverflow上提出問題,你應該編譯這個例子並看到生成的代碼。一切都會變得清晰:
function replaceSpaces($receiver) {
return replace($receiver, 32, 95);
}
function foo(str) {
var formatted = replaceSpaces(str);
}
根本沒有猴子補丁!擴展函數只是Kotlin中的一個語法糖。這只是將第一個參數傳遞給靜態函數的另一種方式。
「不要讓Kotlin項目中的每個開發人員都爲隨機類型添加新擴展」 - >我並不認爲這是個問題。擴展功能在特定範圍內定義,必須導入才能使用。你甚至可以在你的班級中創建本地私人擴展功能。創建擴展函數時不會污染全局名稱空間。 – marstran
但是,當然,只有一個大的「Extensions.kt」文件,所有的擴展函數都是壞的。你必須適當地確定它們的範圍。但這是你必須做的一切,而不僅僅是擴展功能。 – marstran
這不是我所建議的;-)然而,一些紀律是必需的。你是對的,其他任何事情都是如此 – s1m0nw1