zoukankan      html  css  js  c++  java
  • 前端攻城狮学习笔记二:实现一个叫Man的类,包含attr, words, say三个方法。

    面试题目

      这是搜狐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")方式的赋值”问题,如果各位朋友有新的方案,请不吝指点。也欢迎对我的方案拍砖论讨。

  • 相关阅读:
    UVA 10572 Black & White (状压DP)
    ZOJ 3466 The Hive II (插头DP,变形)
    POJ 3133 Manhattan Wiring (插头DP,轮廓线,经典)
    HDU 3377 Plan (插头DP,变形)
    HDU 1964 Pipes (插头DP,变形)
    FZU 1977 Pandora adventure (插头DP,常规)
    URAL 1519 Formula 1 (插头DP,常规)
    POJ 1739 Tony's Tour (插头DP,轮廓线DP)
    HDU 1693 Eat the Trees (插头DP)
    hihoCoder #1162 : 骨牌覆盖问题·三 (矩阵快速幂,DP)
  • 原文地址:https://www.cnblogs.com/jscode/p/2577063.html
Copyright © 2011-2022 走看看