今天在网上看到一条关于面向对象的很形象的题目,决定转过来分享一下。

小贤是一条可爱的小狗(Dog),它的叫声很好听(wow),每次看到主人的时候就会乖乖叫一声(yelp)。

小芒和小贤一样,原来也是一条可爱的小狗,可是突然有一天疯了(MadDog),一看到人就会每隔半秒叫一声(wow)地不停叫唤(yelp)。

请根据描述,按示例的形式用代码来实现(提示关键字: 继承,原型,setInterval)。

正确答案:

<script language=”JavaScript” type=”text/javascript”>
    window.onload = function(){
        function Dog(name){this.name = name;}
        Dog.prototype = {
            constructor : Dog,
            wow: function(){
                alert(‘wow’);
            },
            yelp: function(){
                return this.wow();
            }
        }
        function CrazyDog(name){this.name = name;}
        CrazyDog.prototype = new Dog();
        CrazyDog.prototype.madYelp = function(){
            var _self = this;
            setInterval(function(){
                return _self.yelp();
            }, 2000);
        }
        var xiaoXian = new Dog(“xiaoXian”);
        var xiaoXianBtn = document.getElementById(“xiaoXianBtn”);
        xiaoXianBtn.onclick = function(){xiaoXian.yelp();}
        var xiaoMang = new CrazyDog(“xiaoMang”);
        var xiaoMangBtn = document.getElementById(“xiaoMangBtn”);
        xiaoMangBtn.onclick = function(){xiaoMang.madYelp();}
    }
</script>
 

第一种 prototype 引用型原型继承
语言支持:js原生支持的继承方式 构造器的的prototype属性作为类的原型 每个该类的对象都持有一个到原型的引用 当对象中的属性不存在时 可以访问原型的属性

代码示例:

<script>
function parent(){
this.x=10;
}
function child(){
}
child.prototype=new parent();
var childObj=new child();
alert(childObj.x);
</script>

第二种 复制型原型继承
语言支持:js new运算符的性质 当构造函数return值为非空对象时 new表达式返回return的对象
代码示例:
<script>
function parent(){
this.x=10;
}
function child(){
var ret=new parent();
ret.y=20;
return ret;
}
var childObj=new child();
alert(childObj.x);</script>

第三种 类继承 属性抄写
语言支持:for in枚举对象所有属性
<script>
function parent(){
this.x=10;
}
function child(){
var parentObj=new parent();
for(var p in parentObj)this[p]=parentObj[p];
}
var childObj=new child();
alert(childObj.x);
</script>

第四种 类继承 对象冒充
语言支持: 1.动态添加和删除方法 2.函数的call和apply
代码:
用语言支持1实现的类继承
<script>
function parent(){
this.x=10;
}
function child(){
this.parent=parent;
this.parent();
delete this.parent;
}
var childObj=new child();
alert(childObj.x);</script>

用语言支持2实现的类继承
<script>
function parent(){
this.x=10;
}
function child(){
parent.call(this);
}
var childObj=new child();
alert(childObj.x);</script>

第五种 原型抄写
语言支持:通过修改类的原型对象 可以为一类对象添加属性和方法
代码
<script>
function parent(){}
parent.prototype.me=function(){alert(“parent”)};
function child(){}
for(var p in parent.prototype)child.prototype[p]=parent.prototype[p];
var childObj=new child();
childObj.me();</script>

第六种 元类
语言支持: js函数都是对象 且js函数可被构造
<script>function parent(string){
var child=new Function(“this.x=10;”+string);
return child;
}
var child=new parent(“this.y=20;”);
var childObj=new child();
alert(childObj.y);
</script>

对js对象来说 它的属性来自两部分:prototype属性和自身属性 call/apply只能继承自身属性 原型抄写只能继承prototype属性
将它们混用互相没有任何干扰 而且实现了所有属性的继承。但是我觉得,如果按规范编码的话,似乎只用其一就足够了,对一个类来说,同时给prototype和构造函数添加属性的情况很少见吧?

转自:http://hi.baidu.com/tangdecai/blog/item/6c7e6306698b837d020881ff.html

© 2012 Hedgehog Suffusion theme by Sayontan Sinha