面試題目
這是 搜狐JavaScript面試題 ,要求如下:
實現一個叫Man的類,包含attr, words, say三個方法。
var
Man;
//
+++++++++++答題區域+++++++++++
//
+++++++++++答題結束+++++++++++
try
{
var
me = Man({ fullname: "小紅"
});
var
she =
new
Man({ fullname: "小紅"
});
console.group();
console.info(
"我的名字是:" + me.attr("fullname") + "\n我的性別是:" + me.attr("gender"
));
console.groupEnd();
/*
------[執行結果]------
我的名字是:小紅
我的性別是:<用戶未輸入>
------------------
*/
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();
/*
------[執行結果]------
我的名字是:小明
我的性別是:男
------------------
*/
console.group();
console.info(
"我的名字是:" + she.attr("fullname") + "\n我的性別是:" + she.attr("gender"
));
console.groupEnd();
/*
------[執行結果]------
我的名字是:小紅
我的性別是:女
------------------
*/
me.attr({
"words-limit": 3
,
"words-emote": "微笑"
});
me.words(
"我喜歡看視頻。"
);
me.words(
"我們的辦公室太漂亮了。"
);
me.words(
"視頻里美女真多!"
);
me.words(
"我平時都看優酷!"
);
console.group();
console.log(me.say());
/*
------[執行結果]------
小明微笑:"我喜歡看視頻。我們的辦公室太漂亮了。視頻里美女真多!"
------------------
*/
me.attr({
"words-limit": 2
,
"words-emote": "喊"
});
console.log(me.say());
console.groupEnd();
/*
------[執行結果]------
小明喊:"我喜歡看視頻。我們的辦公室太漂亮了。"
------------------
*/
}
catch
(e){
console.error(
"執行出錯,錯誤信息: " +
e);
}
分析過程
分析如下:
從實例化對象的方式看,用new或不用都可以,這是一種作用域安全構造函數,原理就是檢查this是不是指向當前方法本身,如果不是就強制new一個對象出來。所以大體框架如下:
Man=
function
(obj){
if
(
this
instanceof
arguments.callee){
for
(
var
e
in
obj){
this
[e]=
obj[e];
}
}
else
{
return
new
Man(obj);
}
};
通過觀察可以發現,attr方法可以獲取或設置屬性值,并且參數可以是一個字符串,一個字符串加一個值,一個對象。所以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可以發現,這里就是傳入了一些字符串,以便在say方法中調用,所以這里直接給Man添加一個words_limit_arr的數組,用來存放這些字符串,所以words方法實現如下:
Man.prototype.words=
function
(str){
this
.words_limit_arr.push(str);
}
最后就是say方法了,通過觀察可以發現,say方法就是把fullname屬性的值加上limit-emote的值,再加上前words-limit個words_limit_arr項連接成的字符串,所以定義如下:
Man.prototype.say=
function
(){
return
this
["fullname"]+
this
["words-emote"]+":"+"\""+
this
.words_limit_arr.slice(0,
this
["words-limit"]).join("")+"\""
;
}
整個合起來就是:
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("")+"\""
;
}
但其中有個問題沒有解決,就是用me.fullname="xxx"方式的賦值不能改變me.attr("fullname","xxx")方式的賦值。這個問題導致運行效果如下:
這個問題要如何解決呢,我一直沒想到,后來參考了別人的代碼,那位朋友的思路是讓me.attr("fullname","xxx")方式對fullname的賦值跟me.fullname不是同一個屬性。
在沒想到其他方案之前,我也只好把我的代碼修改如下:
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("")+"\""
;
}
修改后運行效果如下:
小結
本面試題主要考查了 作用域安全構造函數,instanceof/typeof 的用法,slice的用法,對數組的遍歷,對對象成員的遍歷等知識點。
關于上面提到的“用me.fullname="xxx"方式的賦值不能改變me.attr("fullname","xxx")方式的賦值”問題,如果各位朋友有新的方案,請不吝指點。也歡迎對我的方案拍磚論討。
更多文章、技術交流、商務合作、聯系博主
微信掃碼或搜索:z360901061
微信掃一掃加我為好友
QQ號聯系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元

