摘要:內部維護一個叫的局部變量,數組類型,用于存儲購買的物品清單。分析看到這題的第一反應就是用構造函數來寫。二屬性外部只能訪問不能修改這個用閉包也能解決,但是這樣記不能通過構造函數來實現了,背離了初衷,不行不過我后面還是會給出這種寫法。
背景
作為一個前端新人,免不了加各種群,和其他小伙伴們一起學習(chui bi),互相幫助(bi can)。前幾天一個小伙伴在群里發了道自己去面試的筆試題,我寫了一下,一時間沒能實現,今天又折騰了一下,雖然大致實現了,但不知道是否優雅,分享自己解法的同時也想請大佬指點一二。
題目 編寫一個名字為Person的對象,要求有一個name屬性,外部只能訪問不能修改,初始化時賦值。
內部維護一個叫things的局部變量,數組類型,用于存儲購買的物品(something)清單。
有一個buy(something)方法,用于購買物品(something)
具有count屬性,用于指示一共買了多少物品。
分析看到這題的第一反應就是用構造函數/class來寫。Person對象應該就是一個Person類。
兩個屬性一個方法,嗯,沒什么問題。只有2個點需要考慮:
一、 這個things局部變量是個啥?是屬性嗎?
應該不是,既然特意指出了,肯定有他的考慮,那么既然是局部變量,外部也是訪問不到的,這個應該用閉包寫。
二、 name屬性外部只能訪問不能修改.
這個用閉包也能解決,但是這樣記不能通過構造函數/class來實現了,背離了初衷,不行(不過我后面還是會給出這種寫法)。那么(以我的水平)就只能用Proxy或者class,這2個都能攔截對象屬性的讀/寫。2種我都試過,采用Proxy,原因下面會講。
代碼class Person { constructor(name,count=0) { this.name = name; this.count = count; this.init() } //初始化函數 init() { var things = []; Person.prototype.buy = (something) => { //為了形成閉包,顯式將buy方法寫到Person的原型上 things.push(something); this.count = things.length; } } } //Proxy handler對象,定義行為 var handler = { set(target,prop,value,receiver) {//攔截set行為 if(prop == "name") { throw Error("不可以哦") //這里自定義你的邏輯,也可以alert等。 } Reflect.set(target,prop,value,receiver) //不要忘了對其余屬性"放行" } } var p1 = new Proxy(new Person("張三"),handler) console.log(p1.name) //張三 p1.name = "李四" //Error:不可以哦 p1.buy("貓糧"); p1.buy("貓砂"); console.log(p1.count) //2 //如果需要從"內部"修改p1的名字,則需要先對被代理對象進行定義 var _p1 = new Person("張三"); var p1 = new Proxy(_p1,handler) console.log(p1.name); //張三 _p1.name = "李四"; console.log(p1.name) //李四
以上我對這道題的理解。至于為什么不用class的setter,是因為這樣寫后,在new Person的時候不能傳name進去,因為一傳進去就會被攔截。所以只能先初始化對name賦值,再進行proxy代理對name攔截。
另一種“野路子”寫法var Person = function(name,count=0) { var things = [],name = name result = { count = count; }; result.__proto__ = { buy:function(something) { things.push(something); result.count = things.length; }, getName:function() { // 通過getName函數來獲取名字 return name; } } return result; } var p2 = Person("王五"); p2.getName() //王五 p2.name = 123; p2.getName() //王五 p2.buy("妙鮮包"); console.log(p2.count) // 1
兩種方法見仁見智,第二種野路子不用Proxy代理,返回的是Object對象,而第一種正規軍則返回Person對象,更符合題意。
結語寫到這不知道大家發現了沒。 其實第一種方法也可以不需要proxy代理,再init函數中定義name = this.name,再在Person原型上寫一個getName函數,這樣2種方法的優點就結合到一起了Σ(っ °Д °;)っ
這2小時沒有白花,這文章沒有白寫,又賺到了^ ^。
希望能給大家帶來一點點收獲,如果有不同的看法可以留言一起探討()。
Thanks for reading
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/84226.html
摘要:內容簡介,關于面向對象,關于面向物理模型,示例,總結,關于面向對象中的面向對象是一個老生常談的問題,可能有人問你的話你也能霹靂啪啦的說一通,比如最常見的,對象的三要素對象的名字對象的屬性對象的方法例子對象名示例對象屬性對象方法或者稍微高級一 內容簡介: 1,關于面向對象 2,關于面向物理模型 3,示例 4,總結 1,關于面向對象 javascript中的面向對象是一個老生常談的問...
摘要:然而事實上并不是。函數本身也是一個對象,但是給這個對象添加屬性并不能影響。一圖勝千言作者給出的解決方案,沒有麻煩的,沒有虛偽的,沒有混淆視線的,原型鏈連接不再赤裸裸。所以是這樣的一個函數以為構造函數,為原型。 注意:本文章是個人《You Don’t Know JS》的讀書筆記。在看backbone源碼的時候看到這么一小段,看上去很小,其實忽略了也沒有太大理解的問題。但是不知道為什么,我...
摘要:開始看到的函數和時,非常的模糊,不知所云,然后看書,網上查詢多少知道點了眉目,下面是我做的筆記,希望和大家分享,有不對之處希望各位多多指正,共同進步。。。 開始看到javascript的函數apply和call時,非常的模糊,不知所云,然后看書,網上查詢多少知道點了眉目,下面是我做的筆記,希望和大家分享,有不對之處希望各位多多指正,共同進步。。。本文將從三個方面介紹apply,call...
摘要:剛開始看到的函數和時,非常的模糊,不知所云,然后看書,網上查詢多少知道點了眉目,下面是我做的筆記,希望和大家分享,有不對之處希望各位多多指正,共同進步。。。 剛開始看到javascript的函數apply和call時,非常的模糊,不知所云,然后看書,網上查詢多少知道點了眉目,下面是我做的筆記,希望和大家分享,有不對之處希望各位多多指正,共同進步。。。本文將從三個方面介紹apply,ca...
摘要:閉包是什么這是一個在面試的過程中出現的概率為以上的問題,也是我們張口就來的問題。文章推薦我們面試中在被問到閉包這個問題是要注意的幾點閉包的延伸,讓面試變得 閉包是什么?這是一個在面試的過程中出現的概率為60%以上的問題,也是我們張口就來的問題。但是我們往往發現,在面試的過程中我們的回答并不那么讓面試官滿意,我們雖然能張口說出一些但是卻不能系統的對這個問題進行回答。面試官希望加入自己團隊...
閱讀 2146·2021-10-12 10:11
閱讀 846·2021-10-09 09:41
閱讀 3760·2021-09-09 11:37
閱讀 1940·2021-09-08 10:41
閱讀 2641·2019-08-30 12:58
閱讀 2373·2019-08-30 10:58
閱讀 1278·2019-08-26 13:40
閱讀 4113·2019-08-26 13:36