看板 Web_Design 關於我們 聯絡資訊
大家好最近在唸vue 相信關於為什麼data要使用function已經被討論到爛掉 看了很多講解都是下面的例子 const MyComponent = function() {}; MyComponent.prototype.data ={ a: 1, b: 2, }; const component1 = new MyComponent(); const component2 = new MyComponent(); component1.data.b = 5; console.log(component2.data) ↑因為會共享同一個reference ----------------------------------- 所以應該改成以下function的方式: const MyComponent = function() { this.data = this.data(); }; MyComponent.prototype.data = ()=> { return{ a: 1, b: 2 } }; const component1 = new MyComponent(); const component2 = new MyComponent(); component1.data.b = 5; console.log(component2.data) 但我不太明白的是這個講解,跟是不是function的影響有什麼關係? 因為這邊如果一開始就將data的資料放在constructor裡 像是 const MyComponent = function() { this.data = { a:1, b:2 } }; 每次實例化時就會初始化,所以只要把data放在constructor裡 本來就可以解決問題了,跟是不是function有什麼關係? -------------------------------------------------- 以下為調整過後的範例,對於我自己有比較想通了 希望有助於跟我有一樣有相同問題的人幫助理解 -------------------------------------------------- const MyComponent = function() { this.data = this.data; //Object表示 //this.data = this.data(); //function表示 }; //Object表示 MyComponent.prototype.data ={ a: 1, b: 2 }; // //function表示 // MyComponent.prototype.data = ()=>{ // return{ // a:1, // b:2 // } // } const component1 = new MyComponent(); const component2 = new MyComponent(); component1.data.b = 5; console.log(component2.data) 上面的範例調整了不論使用object或是function的方式 統一條件this.data都放在constructor裡 且也統一調整了獲取的方式都從prototype中拿取 這樣就能單純比較使用object跟使用function的差異 當初卡住的理由是this.data = this.data這行其實就等於原範例中 不寫在constructor的原因,理由是寫與不寫都是從prototype中拿取 當時沒想到這點,所以卡了很久 感謝各位大大! -- ※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 115.43.135.34 (臺灣) ※ 文章網址: https://www.ptt.cc/bbs/Web_Design/M.1688885096.A.532.html
cloki: 你的data不會永遠只用{a:1,b:2},要用別的就會把data拆出來 07/09 21:25
不好意思不太明白,請問這有範例可以呈現嗎?
cloki: 如果只用object的話你直接改就會動讓每個實體的data都變成 07/09 21:26
cloki: 5,如果用callback的話才會讓this.data每次都是新的預設值 07/09 21:26
※ 編輯: heavenbetula (115.43.135.34 臺灣), 07/09/2023 23:18:56
ck574b027: 你的舉例是一樣意思,constructor也是function。不要 07/10 08:02
ck574b027: 在js使用prototype,語意會讓你誤會很多東西。 07/10 08:02
ssccg: function隨時可呼叫,為什麼你會覺得constructor有比較好? 07/10 10:04
ssccg: data又不一定要是在new Component的時候呼叫,獨立的functi 07/10 10:12
ssccg: on之後如果需要取回data預設值,隨時都能呼叫data() 07/10 10:13
ssccg: 怎麼會沒事想去選個最沒彈性的寫法 07/10 10:14
感覺好像偏離了問題 我的疑問不是說哪個方法好 我也沒說constructor比較好 而是想釐清 網路上的解釋是說在constructor中使用了this.data = this.data() 但似乎跟vue為什麼data用function的原因無關? ※ 編輯: heavenbetula (115.43.135.34 臺灣), 07/11/2023 21:18:18
cloki: 因為在設計的概念上就不想直接把data的內容寫進去啊 07/12 16:56
cloki: 然後那個例子就告訴你不用function的話就會把原型內的值一 07/12 16:58
cloki: 併改掉,所以不能用object應該用function,沒弄清楚的話先把 07/12 16:59
cloki: 例如裡面的值都print出來比較一下 07/12 16:59
microloft: 沒有,原po最後一段用obj的寫法就已經不會共用ref了 07/12 18:06
microloft: 所以用func並不是必要,只是一種寫法選擇 07/12 18:07
m大說的對,所以我才會想說為什麼網路上一堆解釋都是用這個範例 ※ 編輯: heavenbetula (115.43.135.34 臺灣), 07/14/2023 21:48:50
cloki: 感謝m大 原來我理解是錯的 那分別就只是那是沒有es6的寫法? 07/15 01:50
microloft: 如果我沒弄錯,那寫法/機制應該上古時期就有了, 07/15 02:47
microloft: ES6只多加入了更直觀的class宣告語法。 07/15 02:47
microloft: 所以多套一層func除了上面提到的回復預設值外, 07/15 02:48
microloft: 老實說我也想不到還有什麼其他好處... 07/15 02:49
ck574b027: 不會共用的原因是因為用了function,只是前者叫data() 07/16 10:55
ck574b027: 後者是constructor,不要誤導人 07/16 10:56
ck574b027: 為何要用前者當範例,因為是好習慣 07/16 11:11
ck574b027: 與其糾結這個不如去看vue3 07/16 11:12
microloft: 並不是,原po共列了3種寫法,1會共用,2跟3不會。 07/16 17:26
microloft: 根本的差別是1直接操作原型鍊物件的data的屬性, 07/16 17:26
microloft: 2跟3則寫在建構子裡,在初始化時會另生一份。 07/16 17:26
microloft: 所以賦值給data時是用func(2)還是物件(3)並不是 07/16 17:26
microloft: 是否會共用的原因。 07/16 17:26
microloft: 範例2裡的data()從來就沒有扮演建構子的角色 07/16 17:30
microloft: 1~3的建構子都同樣是MyComponent 07/16 17:32
ck574b027: 這樣講沒有觸碰到本質,物件(3)不會共用是因為他的位置 07/19 00:18
ck574b027: 在建構子。偷用了正確方式來說他是對的根本狐假虎威 07/19 00:20
ck574b027: 把範例的建構子拿掉,在new之後才賦值給data比較清楚 07/19 00:22
ck574b027: (2) component1.data = init() 07/19 00:24
ck574b027: (3) component1.data = {...} 07/19 00:24
ck574b027: 說func不是必要,結果利用的建構子還是func,你紹安嗎 07/19 00:30
microloft: 麻煩你看清楚,原po這篇本來就是在問為什麼都移到建構 07/19 01:55
microloft: 子裡了還要多用data()這個func,前面有人說是因為共用 07/19 01:56
microloft: 問題,我才會回覆說func並不是必要,因為根本的原因不 07/19 01:56
microloft: 在那裡 07/19 01:56
microloft: 另外你提到的「本質」我前面明明就講過一樣的了... 07/19 02:09
ssccg: 我覺得是原PO死讀書,雖然教學說data用function是避免重複 07/21 10:18
ssccg: 用到同一個物件,但那就不是唯一的原因啊,本來就有很多方 07/21 10:20
ssccg: 法達成這個效果,我相信寫講解的人也只是要表示「有這個效 07/21 10:21
ssccg: 果是設計目標之一」而不是「只有這個設計能達這效果」 07/21 10:22
ssccg: 甚至就放prototype但新建Component時固定做deep clone也行 07/21 10:25
ssccg: 啊,不用獨立function也不用constructor啊 07/21 10:27
ssccg: 用function只是充分條件,但原PO似乎堅持一定要充要條件(只 07/21 10:28
ssccg: 有用function才能達成這效果)才叫做「有關」,只要有其他實 07/21 10:29
ssccg: 作就叫無關,莫名奇妙死腦筋 07/21 10:29
我知道有許多方法啊 但我就是其中一點不明白才會只針對這一點詢問 假如我是一個程式小白,我對for迴圈不明白 難道你跟我講解多個迴圈方式 會對我針對for迴圈不明白這件事有幫助嗎 所以我才會說這偏離的問題
ssccg: 現實就是很多方法,再用別的條件來挑哪個方法好(或比較不壞 07/21 10:30
ssccg: )但原PO埾持這叫做偏離問題,那就自己去想再久也想不通吧 07/21 10:30
ssccg: 為什麼網路上一堆解釋都是用這個範例,講白一點就是覺得對 07/21 10:30
ssccg: 新手不用講這麼多啦,啊對老手自然會自己想通才不會這樣卡 07/21 10:31
ssccg: 住腦子轉不動 07/21 10:31
ssccg: 要講其他考量那可多了,constructor最不好的就是呼叫時機很 07/21 10:36
ssccg: 死一定在最前面啊,如果想把Component建立和data初始化中間 07/21 10:37
ssccg: 切個階段出來就不行了。另外像用function而不用clone的理由 07/21 10:39
ssccg: 顯然是function內容是呼叫時執行,而不像物件早就填進去了 07/21 10:46
首先我想澄清一下,如果我只是死讀書,我大可背下這個解法就好 我又何必去追問這個的原因是為什麼 這邊每個大大來回答解惑我都很感激 但不表示我不能表達我覺得有疑問的地方 其實這一版看多了許多發問的問題 往往都會被洗臉甚至被認為這種問題沒什麼好問 只希望大家都可以將心比心 想想每個人都有新手的時候 謝謝 ※ 編輯: heavenbetula (115.43.135.34 臺灣), 07/22/2023 13:00:11 ※ 編輯: heavenbetula (115.43.135.34 臺灣), 07/22/2023 14:18:25 ※ 編輯: heavenbetula (115.43.135.34 臺灣), 07/22/2023 14:22:02 ※ 編輯: heavenbetula (115.43.135.34 臺灣), 07/22/2023 14:28:45