簡體   English   中英

通過組合創建的對象上的方法無法訪問所有屬性

[英]Methods on an object created via composition can't access all properties

我正在為產品構建家庭的概念,成員具有不同的類型( accountHolderpayingCustomerstudent等)。 最初我將這些作為FamilyMember子類FamilyMember ,但我最終得到了一些重復的代碼,最終遇到了一個重大問題:我們平台的student也可以是唯一的payingCustomeraccountHolder

鑒於對象組合在 JS 中被廣泛吹捧為一個好主意,我決定走這條路。 但是,特定對象類型(例如accountHolder )的方法不能訪問實例化對象的屬性,如果該屬性屬於另一個對象類型(例如student )。

為了使這更客觀,我決定使用以下代碼復制行為:

const person = (props) => {
  let state = {
    name: props.name,
  }

  state.isOfAge = () => {
    // state.isAdult is always undefined because
    // isAdult doesn't exist in this object
    return state.isAdult === true
  }

  return state
}

const adult = (props) => {
  return {
    isAdult: true,
  }
}

const factory = (props) => {
  return Object.assign({}, person(props), adult(props))
}

const john = factory({
  name: 'John',
})

console.clear()
console.log(john) // { isAdult: true, name: "John", isOfAge... }
console.log(john.isOfAge()) // false

我期待john的方法isOfAge能夠訪問屬性isAdult ,因為它在對象中。 但是,從概念上講,我理解為什么它不起作用: isOfAge是一種state方法,而不是生成的adult實例。

如果我使用類,甚至是傳統的原型/構造器機制,我知道如何使其工作(例如附加到prototype )。 對於對象組合,我不知道如何到達那里,可能是由於缺乏 FP 的經驗。

謝謝您的幫助!

您可以在isOfAge使用this而不是state 這樣,當方法isOfAge被調用時, this將被推斷,它將被綁定到它被調用的任何對象。 但是,您必須使用常規函數而不是箭頭函數才能工作(箭頭函數沒有this ):

 const person = (props) => { let state = { name: props.name, } state.isOfAge = function() { // use a regular function return this.isAdult === true // use this here instead of state } return state } const adult = (props) => { return { isAdult: true, } } const factory = (props) => { return Object.assign({}, person(props), adult(props)) } const john = factory({ name: 'John', }) console.log(john); console.log(john.isOfAge()); // returns 'true' because 'this' inside 'isOfAge' will be 'john'

對象組合

  • 串聯通過使用新屬性擴展現有對象來組合對象,例如Object.assign(destination, a, b), {...a, ...b}
    ...
    對象組合的隱藏寶藏


所以從你的模式和工廠函數的使用來看,它看起來像連接? 下面的演示是一個串聯組合。 請注意圍繞payment括號的括號:

 const payment = (status) => ({...})

這允許payment作為對象而不是函數返回。 如果您的數據更靈活一些,您將需要更少的方法。 name: stringage: number是我使用的屬性,認為它實用,或者在你的情況下name: stringadult: boolean


演示

 const payment = (status) => ({ adult: () => status.age > 17 ? true : false, account: () => status.adult() ? 'holder' : 'student' }); const member = (name, age) => { let status = { name, age }; return Object.assign(status, payment(status)); }; const soze = member('Kaiser Soze', 57); console.log(soze); console.log(soze.adult()); console.log(soze.account()); const jr = member('Kaiser Soze Jr.', 13); console.log(jr); console.log(jr.adult()); console.log(jr.account());

暫無
暫無

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

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