簡體   English   中英

CoffeeScript繼承; 基類中的數組變為靜態?

[英]CoffeeScript inheritance; Array in base-class becomes static?

來自C ++ / Java背景,CoffeeScript中的OOP繼承使我感到困惑。

考慮以下示例:

class BaseClass
    arr: []

    addItem: (item) =>
        @arr.push item

class SubClassA extends BaseClass
    constructor: ->
        @addItem("fromSubA")

class SubClassB extends BaseClass


console.log "Case 1"
instB = new BaseClass()
instA = new SubClassA()
console.log "instA: #{JSON.stringify instA.arr}"
console.log "instB #{JSON.stringify instB.arr}"

console.log "Case 2"
instB = new SubClassB()
instA = new SubClassA()
console.log "instA: #{JSON.stringify instA.arr}"
console.log "instB #{JSON.stringify instB.arr}"

console.log "Case 3"
instB = new SubClassB()
instA = new SubClassA()
console.log "instA: #{JSON.stringify instA.arr}"
console.log "instB #{JSON.stringify instB.arr}"

在tinkerbin.com中輸出:

Case 1
instA: ["fromSubA"] 
instB ["fromSubA"] 

Case 2
instA: ["fromSubA","fromSubA"] 
instB ["fromSubA","fromSubA"] 

Case 3
instA: ["fromSubA","fromSubA","fromSubA","Added manually, only to instB"] 
instB ["fromSubA","fromSubA","fromSubA","Added manually, only to instB"] 

低:基類的“ arr”實例屬性的行為或多或少就像是靜態屬性一樣; 如果我在一個實例中更改了數組,那么在另一實例中也更改了。 為什么在實例之間共享此數組?

令人困惑的是,字符串屬性沒有表現出以下行為:

class BaseClass
    property: "From Base"    

class SubClassA extends BaseClass
    constructor: ->
        @property = "fromSubClassA"

class SubClassB extends BaseClass


document.write "Case 1<br>"
instB = new BaseClass()
instA = new SubClassA()
document.write "#{instA.property} <br>"
document.write "#{instB.property} <br><br>"

document.write "Case 2<br>"
instB = new SubClassB()
instA = new SubClassA()
instA.property = "test"
document.write "#{instA.property} <br>"
document.write "#{instB.property} <br>"

這段代碼可以正常工作,將實例之間的“屬性”屬性保持隔離。

我在這里顯然誤會了一些東西。 是什么導致陣列在實例之間共享?

看一下生成的JavaScript是什么樣的:

var BaseClass,
  __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; };

BaseClass = (function() {
  function BaseClass() {
    this.addItem = __bind(this.addItem, this);
  }

  BaseClass.prototype.arr = [];

  return BaseClass;

})();

如您所見, arrBaseClass 原型的屬性,就像Python這樣的語言中的類變量一樣。 該數組只有一個實例存在,並且在該類的所有實例之間共享,因此,如果您對其進行修改,則會在所有地方對其進行修改(通過訪問instance.arr ,您將遍歷原型鏈直至同一BaseClass.prototype.arr數組)。

字符串在JavaScript中是不可變的,因此在這方面它們的行為不像數組。

在您的示例中, arr是一個類(即靜態) 屬性 變量,因此它與BaseClass所有實例共享。

您需要編輯BaseClass並在constructor方法中初始化arr屬性:

class BaseClass
    constructor: ->
        @arr = []

    addItem: (item) =>
        @arr.push item

然后,您要確保SubClassA正在使用super()關鍵字調用BaseClass構造函數:

class SubClassA extends BaseClass
    constructor: ->
        super()
        @addItem("fromSubA")

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM