Javascript鸭子打字的例子?

一些程序员建议不要在 Javascript中使用伪古典继承,但建议使用鸭式打字,并为每个对象提供一组功能.

有没有一个很好的例子呢?我下面有一个例子,但是它一次只能分配一个函数.我们可以将一组方法分配给一个对象,例如我们可以设置一个可以“游泳”,“潜水”和“上升”的OceanAnimal的原型,这是一个用于“跑”,“走”的LandAnimal的原型,“跳”,让一个对象从一个还是两个继承? (所以一个鱼类对象可以继承或获得OceanAnimal的功能,一只龟可以获得OceanAnimal和LandAnimal的功能吗?)

var yoyo = {
    name: "Yoyo",type: "turtle"
}

var simba = {
    name: "Simba",type: "lion"
}

var dolphy = {
    name: "Dolphy",type: "dolphin"
}

function swim(n) {
    console.log("My name is",this.name,",I am a",this.type,"and I just swam",n,"feet")
}

function run(n) {
    console.log("My name is","and I just ran","feet")
}

Object.prototype.respondTo = function(method) {
    return !!(this[method] && (typeof this[method] === "function"));
}

yoyo.swim = swim;
yoyo.swim(10);

dolphy.swim = swim;
dolphy.swim(80);

simba.run = run;
simba.run(200);

yoyo.run = run;
yoyo.run(2);

yoyo.walk = run;
yoyo.walk(1);

console.log(simba.respondTo("swim"));
console.log(simba.respondTo("run"));
console.log(simba.respondTo("walk"));

console.log(yoyo.respondTo("run"));
console.log(yoyo.respondTo("walk"));
console.log(yoyo.respondTo("fly"));

if(dolphy.respondTo("run")) {
    dolphy.run(10);
}

if(dolphy.respondTo("swim")) {
    dolphy.swim(10);
}

输出:

My name is Yoyo,I am a turtle and I just swam 10 feet 
My name is Dolphy,I am a dolphin and I just swam 80 feet 
My name is Simba,I am a lion and I just ran 200 feet 
My name is Yoyo,I am a turtle and I just ran 2 feet 
My name is Yoyo,I am a turtle and I just ran 1 feet 
false 
true 
false 
true 
true 
false 
My name is Dolphy,I am a dolphin and I just swam 10 feet

解决方法

JavaScript中的功能是通用的.它们可以用作 subroutines,methods,constructors,namespaces,modules等等.

人们建议在JavaScript中使用伪古典继承的原因是因为它隐藏了JavaScript的真正力量.功能如果不是比对象更具表现力,就是表现力.这已经被Alonzo Church的工作证明了,Lambda CalculusTuring Complete.

要直接回答您的问题,我将使用功能来创建龟,狮子和海豚.然后,我将演示一只海龟是一个海洋动物和一个土地动物,一只狮子如何只是一个LandAnimal,以及一只海豚只是一个海洋动物.最后我将解释鸭子打字是什么.

首先让我们创建一个OceanAnimal的构造函数:

function OceanAnimal() {
    this.swim = function (n) {
        return "I am " + this.name + ",the " + this.type +
               ",and I just swam " + n + " meters.";
    };
}

接下来我们将为LandAnimal创建一个构造函数:

function LandAnimal() {
    this.walk = function (n) {
        return "I am " + this.name + ",and I just walked " + n + " meters.";
    };
}

好的.所以现在让我们创建一个Turtle的构造函数:

Turtle.prototype.type = "turtle";

function Turtle(name) {
    this.name = name;
    LandAnimal.call(this);
    OceanAnimal.call(this);
}

这里发生了什么好的,我们希望海龟继承自OceanAnimal和LandAnimal.所以我们打电话给LandAnimal.call(this)和OceanAnimal.call(this).这样,我们使用OceanAnimal和LandAnimal构造函数为mixins.因此,Turtle从OceanAnimal和LandAnimal继承,实际上并没有成为OceanAnimal或LandAnimal类型.

另外需要注意的是,我们在Turtle的原型上设置了type属性,而不是在其中.这是因为所有海龟的类型是相同的.因此它是共享的.另一方面,每个乌龟的名称可能会有所不同,因此它被设置在构造函数内.

现在我们来类似地为Lion创建一个构造函数:

Lion.prototype.type = "lion";

function Lion(name) {
    this.name = name;
    LandAnimal.call(this);
}

由于Lion是一个LandAnimal,我们只能在LandAnimal构造函数中进行混合.

同样的海豚:

Dolphin.prototype.type = "dolphin";

function Dolphin(name) {
    this.name = name;
    OceanAnimal.call(this);
}

现在我们已经创建了所有的构造函数,让我们创建一个乌龟,一只狮子和一只海豚:

var yoyo = new Turtle("Yoyo");
var simba = new Lion("Simba");
var dolphy = new Dolphin("Dolphy");

Awww,现在让我们自由:

alert(yoyo.walk(10));
alert(yoyo.swim(30));   // turtles are faster in the water
alert(simba.walk(20));
alert(dolphy.swim(20));

哈哈.蛮好玩的.我个人爱Yoyo最多.

那么鸭鸭打字是什么?我们知道yoyo是一个海洋动物和一个LandAnimal.然而,如果我们做了一个OceanAnimal的yoyo实例或者是一个LandAnimal的yoyo实例,那么它返回false.什么?

>你:愚蠢的JavaScript.龟是海洋动物和土地动物!
> JavaScript:不是我站在哪里我只知道这是一只乌龟.
>你:但是如果它游泳,那么它是一个海洋动物,如果它走,那么它是一个LandAnimal.

所以既然JavaScript是这样一个派对,我们必须创建自己的测试来检查一个对象是否是一个OceanAnimal,如果它是一个LandAnimal.

我们从海洋动物开始:

function isOceanAnimal(object) {
    if (typeof object !== "object") return false;
    if (typeof object.swim !== "function") return false;
    return true;
}

同样,对于LandAnimal:

function isLandAnimal(object) {
    if (typeof object !== "object") return false;
    if (typeof object.walk !== "function") return false;
    return true;
}

所以现在我们可以使用isOceanAnimal(yoyo)而不是yoyo instanceof OceanAnimal,而isLandAnimal(yoyo)而不是yoyo的LandAnimal实例;并且这两个功能将为我们所爱的yoyo恢复正确.好极了!

这是一个简单的例子,用于在JavaScript中打字.总结:

When I see a bird that walks like a duck and swims like a duck and quacks like a duck,I call that bird a duck.

同理:

When I see an animal which swims like an ocean animal,I call that animal an ocean animal; and when I see an animal which walks like a land animal,I call that animal a land animal.

编辑:您可以看到上面的代码在这里:http://jsfiddle.net/aaditmshah/X9M4G/

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


kindeditor4.x代码高亮功能默认使用的是prettify插件,prettify是Google提供的一款源代码语法高亮着色器,它提供一种简单的形式来着色HTML页面上的程序代码,实现方式如下: 首先在编辑器里面插入javascript代码: 确定后会在编辑器插入这样的代码: <pre
这一篇我将介绍如何让kindeditor4.x整合SyntaxHighlighter代码高亮,因为SyntaxHighlighter的应用非常广泛,所以将kindeditor默认的prettify替换为SyntaxHighlighter代码高亮插件 上一篇“让kindeditor显示高亮代码”中已经
js如何实现弹出form提交表单?(图文+视频)
js怎么获取复选框选中的值
js如何实现倒计时跳转页面
如何用js控制图片放大缩小
JS怎么获取当前时间戳
JS如何判断对象是否为数组
JS怎么获取图片当前宽高
JS对象如何转为json格式字符串
JS怎么获取图片原始宽高
怎么在click事件中调用多个js函数
js如何往数组中添加新元素
js如何拆分字符串
JS怎么对数组内元素进行求和
JS如何判断屏幕大小
js怎么解析json数据
js如何实时获取浏览器窗口大小
原生JS实现别踩白块小游戏(五)
原生JS实现别踩白块小游戏(一)