前端攻城狮学习笔记二:实现一个叫Man的类,包

系统 1369 0

面试题目

  这是 搜狐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")方式的赋值。这个问题导致运行效果如下:

前端攻城狮学习笔记二:实现一个叫Man的类,包含attr, words, say三个方法。

  这个问题要如何解决呢,我一直没想到,后来参考了别人的代码,那位朋友的思路是让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("")+"\""
      
        ;

}
      
    

  修改后运行效果如下:

前端攻城狮学习笔记二:实现一个叫Man的类,包含attr, words, say三个方法。

小结

  本面试题主要考查了 作用域安全构造函数,instanceof/typeof 的用法,slice的用法,对数组的遍历,对对象成员的遍历等知识点。

  关于上面提到的“用me.fullname="xxx"方式的赋值不能改变me.attr("fullname","xxx")方式的赋值”问题,如果各位朋友有新的方案,请不吝指点。也欢迎对我的方案拍砖论讨。

前端攻城狮学习笔记二:实现一个叫Man的类,包含attr, words, say三个方法。


更多文章、技术交流、商务合作、联系博主

微信扫码或搜索:z360901061

微信扫一扫加我为好友

QQ号联系: 360901061

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描下面二维码支持博主2元、5元、10元、20元等您想捐的金额吧,狠狠点击下面给点支持吧,站长非常感激您!手机微信长按不能支付解决办法:请将微信支付二维码保存到相册,切换到微信,然后点击微信右上角扫一扫功能,选择支付二维码完成支付。

【本文对您有帮助就好】

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描上面二维码支持博主2元、5元、10元、自定义金额等您想捐的金额吧,站长会非常 感谢您的哦!!!

发表我的评论
最新评论 总共0条评论