※ 本文轉寄自 ptt.cc, 文章原始頁面
標題

[問題] Vue關於data為什麼要用function

時間
留言60則留言,4人參與討論
推噓5 ( 5055 )
大家好最近在唸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

60 則留言

cloki, 1F
你的data不會永遠只用{a:1,b:2},要用別的就會把data拆出來
不好意思不太明白,請問這有範例可以呈現嗎?

cloki, 2F
如果只用object的話你直接改就會動讓每個實體的data都變成

cloki, 3F
5,如果用callback的話才會讓this.data每次都是新的預設值
※ 編輯: heavenbetula (115.43.135.34 臺灣), 07/09/2023 23:18:56

ck574b027, 4F
你的舉例是一樣意思,constructor也是function。不要

ck574b027, 5F
在js使用prototype,語意會讓你誤會很多東西。

ssccg, 6F
function隨時可呼叫,為什麼你會覺得constructor有比較好?

ssccg, 7F
data又不一定要是在new Component的時候呼叫,獨立的functi

ssccg, 8F
on之後如果需要取回data預設值,隨時都能呼叫data()

ssccg, 9F
怎麼會沒事想去選個最沒彈性的寫法
感覺好像偏離了問題 我的疑問不是說哪個方法好 我也沒說constructor比較好 而是想釐清 網路上的解釋是說在constructor中使用了this.data = this.data() 但似乎跟vue為什麼data用function的原因無關?
※ 編輯: heavenbetula (115.43.135.34 臺灣), 07/11/2023 21:18:18

cloki, 10F
因為在設計的概念上就不想直接把data的內容寫進去啊

cloki, 11F
然後那個例子就告訴你不用function的話就會把原型內的值一

cloki, 12F
併改掉,所以不能用object應該用function,沒弄清楚的話先把

cloki, 13F
例如裡面的值都print出來比較一下

microloft, 14F
沒有,原po最後一段用obj的寫法就已經不會共用ref了

microloft, 15F
所以用func並不是必要,只是一種寫法選擇
m大說的對,所以我才會想說為什麼網路上一堆解釋都是用這個範例
※ 編輯: heavenbetula (115.43.135.34 臺灣), 07/14/2023 21:48:50

cloki, 16F
感謝m大 原來我理解是錯的 那分別就只是那是沒有es6的寫法?

microloft, 17F
如果我沒弄錯,那寫法/機制應該上古時期就有了,

microloft, 18F
ES6只多加入了更直觀的class宣告語法。

microloft, 19F
所以多套一層func除了上面提到的回復預設值外,

microloft, 20F
老實說我也想不到還有什麼其他好處...

ck574b027, 21F
不會共用的原因是因為用了function,只是前者叫data()

ck574b027, 22F
後者是constructor,不要誤導人

ck574b027, 23F
為何要用前者當範例,因為是好習慣

ck574b027, 24F
與其糾結這個不如去看vue3

microloft, 25F
並不是,原po共列了3種寫法,1會共用,2跟3不會。

microloft, 26F
根本的差別是1直接操作原型鍊物件的data的屬性,

microloft, 27F
2跟3則寫在建構子裡,在初始化時會另生一份。

microloft, 28F
所以賦值給data時是用func(2)還是物件(3)並不是

microloft, 29F
是否會共用的原因。

microloft, 30F
範例2裡的data()從來就沒有扮演建構子的角色

microloft, 31F
1~3的建構子都同樣是MyComponent

ck574b027, 32F
這樣講沒有觸碰到本質,物件(3)不會共用是因為他的位置

ck574b027, 33F
在建構子。偷用了正確方式來說他是對的根本狐假虎威

ck574b027, 34F
把範例的建構子拿掉,在new之後才賦值給data比較清楚

ck574b027, 35F
(2) component1.data = init()

ck574b027, 36F
(3) component1.data = {...}

ck574b027, 37F
說func不是必要,結果利用的建構子還是func,你紹安嗎

microloft, 38F
麻煩你看清楚,原po這篇本來就是在問為什麼都移到建構

microloft, 39F
子裡了還要多用data()這個func,前面有人說是因為共用

microloft, 40F
問題,我才會回覆說func並不是必要,因為根本的原因不

microloft, 41F
在那裡

microloft, 42F
另外你提到的「本質」我前面明明就講過一樣的了...

ssccg, 43F
我覺得是原PO死讀書,雖然教學說data用function是避免重複

ssccg, 44F
用到同一個物件,但那就不是唯一的原因啊,本來就有很多方

ssccg, 45F
法達成這個效果,我相信寫講解的人也只是要表示「有這個效

ssccg, 46F
果是設計目標之一」而不是「只有這個設計能達這效果」

ssccg, 47F
甚至就放prototype但新建Component時固定做deep clone也行

ssccg, 48F
啊,不用獨立function也不用constructor啊

ssccg, 49F
用function只是充分條件,但原PO似乎堅持一定要充要條件(只

ssccg, 50F
有用function才能達成這效果)才叫做「有關」,只要有其他實

ssccg, 51F
作就叫無關,莫名奇妙死腦筋
我知道有許多方法啊 但我就是其中一點不明白才會只針對這一點詢問 假如我是一個程式小白,我對for迴圈不明白 難道你跟我講解多個迴圈方式 會對我針對for迴圈不明白這件事有幫助嗎 所以我才會說這偏離的問題

ssccg, 52F
現實就是很多方法,再用別的條件來挑哪個方法好(或比較不壞

ssccg, 53F
)但原PO埾持這叫做偏離問題,那就自己去想再久也想不通吧

ssccg, 54F
為什麼網路上一堆解釋都是用這個範例,講白一點就是覺得對

ssccg, 55F
新手不用講這麼多啦,啊對老手自然會自己想通才不會這樣卡

ssccg, 56F
住腦子轉不動

ssccg, 57F
要講其他考量那可多了,constructor最不好的就是呼叫時機很

ssccg, 58F
死一定在最前面啊,如果想把Component建立和data初始化中間

ssccg, 59F
切個階段出來就不行了。另外像用function而不用clone的理由

ssccg, 60F
顯然是function內容是呼叫時執行,而不像物件早就填進去了
首先我想澄清一下,如果我只是死讀書,我大可背下這個解法就好 我又何必去追問這個的原因是為什麼 這邊每個大大來回答解惑我都很感激 但不表示我不能表達我覺得有疑問的地方 其實這一版看多了許多發問的問題 往往都會被洗臉甚至被認為這種問題沒什麼好問 只希望大家都可以將心比心 想想每個人都有新手的時候 謝謝
※ 編輯: 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