面試題目
這是 搜狐JavaScript面試題 ,要求如下:
實(shí)現(xiàn)一個(gè)叫Man的類,包含attr, words, say三個(gè)方法。
var Man; // +++++++++++答題區(qū)域+++++++++++ // +++++++++++答題結(jié)束+++++++++++ try { var me = Man({ fullname: "小紅" }); var she = new Man({ fullname: "小紅" }); console.group(); console.info( "我的名字是:" + me.attr("fullname") + "\n我的性別是:" + me.attr("gender" )); console.groupEnd(); /* ------[執(zhí)行結(jié)果]------ 我的名字是:小紅 我的性別是:<用戶未輸入> ------------------ */ me.attr( "fullname", "小明" ); me.attr( "gender", "男" ); me.fullname = "廢柴" ; me.gender = "人妖" ; she.attr( "gender", "女" ); console.group(); console.info( "我的名字是:" + me.attr("fullname") + "\n我的性別是:" + me.attr("gender" )); console.groupEnd(); /* ------[執(zhí)行結(jié)果]------ 我的名字是:小明 我的性別是:男 ------------------ */ console.group(); console.info( "我的名字是:" + she.attr("fullname") + "\n我的性別是:" + she.attr("gender" )); console.groupEnd(); /* ------[執(zhí)行結(jié)果]------ 我的名字是:小紅 我的性別是:女 ------------------ */ me.attr({ "words-limit": 3 , "words-emote": "微笑" }); me.words( "我喜歡看視頻。" ); me.words( "我們的辦公室太漂亮了。" ); me.words( "視頻里美女真多!" ); me.words( "我平時(shí)都看優(yōu)酷!" ); console.group(); console.log(me.say()); /* ------[執(zhí)行結(jié)果]------ 小明微笑:"我喜歡看視頻。我們的辦公室太漂亮了。視頻里美女真多!" ------------------ */ me.attr({ "words-limit": 2 , "words-emote": "喊" }); console.log(me.say()); console.groupEnd(); /* ------[執(zhí)行結(jié)果]------ 小明喊:"我喜歡看視頻。我們的辦公室太漂亮了。" ------------------ */ } catch (e){ console.error( "執(zhí)行出錯(cuò),錯(cuò)誤信息: " + e); }
分析過程
分析如下:
從實(shí)例化對(duì)象的方式看,用new或不用都可以,這是一種作用域安全構(gòu)造函數(shù),原理就是檢查this是不是指向當(dāng)前方法本身,如果不是就強(qiáng)制new一個(gè)對(duì)象出來。所以大體框架如下:
Man= function (obj){ if ( this instanceof arguments.callee){ for ( var e in obj){ this [e]= obj[e]; } } else { return new Man(obj); } };
通過觀察可以發(fā)現(xiàn),attr方法可以獲取或設(shè)置屬性值,并且參數(shù)可以是一個(gè)字符串,一個(gè)字符串加一個(gè)值,一個(gè)對(duì)象。所以attr方法定義如下:
Man.prototype.attr= function (attr,val){ if (val){ this [attr]= val; } else { if ( typeof attr === "string" ){ return this .hasOwnProperty(attr)? this [attr]:"<用戶未輸入>" ; } else if ( typeof attr === "object" ){ for ( var e in attr){ this [e]= attr[e]; } } else { } } }
通過觀察words可以發(fā)現(xiàn),這里就是傳入了一些字符串,以便在say方法中調(diào)用,所以這里直接給Man添加一個(gè)words_limit_arr的數(shù)組,用來存放這些字符串,所以words方法實(shí)現(xiàn)如下:
Man.prototype.words= function (str){ this .words_limit_arr.push(str); }
最后就是say方法了,通過觀察可以發(fā)現(xiàn),say方法就是把fullname屬性的值加上limit-emote的值,再加上前words-limit個(gè)words_limit_arr項(xiàng)連接成的字符串,所以定義如下:
Man.prototype.say= function (){ return this ["fullname"]+ this ["words-emote"]+":"+"\""+ this .words_limit_arr.slice(0, this ["words-limit"]).join("")+"\"" ; }
整個(gè)合起來就是:
var Man= function (obj){ if ( this instanceof arguments.callee){ for ( var e in obj){ this [e]= obj[e]; } this .words_limit_arr= []; } else { return new Man(obj); } }; Man.prototype.attr = function (attr,val){ if (val){ this [attr]= val; } else { if ( typeof attr === "string" ){ return this .hasOwnProperty(attr)? this [attr]:"<用戶未輸入>" ; } else if ( typeof attr === "object" ){ for ( var e in attr){ this [e]= attr[e]; } } else { } } } Man.prototype.words = function (str){ this .words_limit_arr.push(str); } Man.prototype.say = function (){ return this ["fullname"]+ this ["words-emote"]+":"+"\""+ this .words_limit_arr.slice(0, this ["words-limit"]).join("")+"\"" ; }
但其中有個(gè)問題沒有解決,就是用me.fullname="xxx"方式的賦值不能改變me.attr("fullname","xxx")方式的賦值。這個(gè)問題導(dǎo)致運(yùn)行效果如下:
這個(gè)問題要如何解決呢,我一直沒想到,后來參考了別人的代碼,那位朋友的思路是讓me.attr("fullname","xxx")方式對(duì)fullname的賦值跟me.fullname不是同一個(gè)屬性。
在沒想到其他方案之前,我也只好把我的代碼修改如下:
var Man= function (obj){ if ( this instanceof arguments.callee){ this .infos= { }; for ( var e in obj){ this .infos[e]= obj[e]; } this .words_limit_arr= []; } else { return new Man(obj); } }; Man.prototype.attr = function (attr,val){ if (val){ this .infos[attr]= val; } else { if ( typeof attr === "string" ){ return this .infos[attr]? this .infos[attr]:"<用戶未輸入>" ; } else if ( typeof attr === "object" ){ for ( var e in attr){ this .infos[e]= attr[e]; } } else { } } } Man.prototype.words = function (str){ this .words_limit_arr.push(str); } Man.prototype.say = function (){ return this .infos["fullname"]+ this .infos["words-emote"]+":"+"\""+ this .words_limit_arr.slice(0, this .infos["words-limit"]).join("")+"\"" ; }
修改后運(yùn)行效果如下:
小結(jié)
本面試題主要考查了 作用域安全構(gòu)造函數(shù),instanceof/typeof 的用法,slice的用法,對(duì)數(shù)組的遍歷,對(duì)對(duì)象成員的遍歷等知識(shí)點(diǎn)。
關(guān)于上面提到的“用me.fullname="xxx"方式的賦值不能改變me.attr("fullname","xxx")方式的賦值”問題,如果各位朋友有新的方案,請(qǐng)不吝指點(diǎn)。也歡迎對(duì)我的方案拍磚論討。
前端攻城獅學(xué)習(xí)筆記二:實(shí)現(xiàn)一個(gè)叫Man的類,包含attr, words, say三個(gè)方法。
更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號(hào)聯(lián)系: 360901061
您的支持是博主寫作最大的動(dòng)力,如果您喜歡我的文章,感覺我的文章對(duì)您有幫助,請(qǐng)用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點(diǎn)擊下面給點(diǎn)支持吧,站長非常感激您!手機(jī)微信長按不能支付解決辦法:請(qǐng)將微信支付二維碼保存到相冊(cè),切換到微信,然后點(diǎn)擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對(duì)您有幫助就好】元
