本文介绍了Javascript Duck打字的例子?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

一些程序员建议不要在Javascript中使用伪经典继承,但建议使用duck-typing并为每个对象赋予一组功能。

Some programmers advise against using pseudo classical inheritance in Javascript, but advise using duck-typing and giving each object a set of capabilities.

是否有一个很好的例子怎么做的?我在下面有一个例子,但它一次只分配一个函数。我们可以为一个对象分配一组方法,例如我们可以设置 OceanAnimal 的原型,它可以游泳,潜水和上升,用于run,walk和jump的 LandAnimal 的原型,让一个对象从其中一个或两个继承? (所以fish对象可以继承或获得 OceanAnimal 的功能,而且一只乌龟可以获得 OceanAnimal 的功能和 LandAnimal ?)

Is there a good example of how that is done? I have an example down below, but it only assign function one at a time. Can we assign a whole group of methods to an object, such as can we set a prototype of OceanAnimal which can "swim", "dive", and "rise", a prototype of LandAnimal for "run", "walk", and "jump", and let an object inherit from one or both of them? (so a fish object can inherit or get the capabilities of OceanAnimal, and a turtle can get the capabilities of both OceanAnimal and 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", this.name,  ", I am a", this.type, "and I just ran", n, "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中的函数是通用的。它们可以用作,,,,等等。

Functions in JavaScript are versatile. They can be used as subroutines, methods, constructors, namespaces, modules, and much more.

人们建议不要在JavaScript中使用伪古典继承是因为它隐藏了JavaScript的真正威力。如果不是比对象更具表现力,那么函数就像表达一样。 的工作证明了这一点,,。

The reason people advise against using pseudo classical inheritance in JavaScript is because it hides the true power of JavaScript. Functions are just as expressive if not more expressive than objects. This has been proven by Alonzo Church who's work, Lambda Calculus, is Turing Complete.

要直接回答你的问题,我将使用函数创建一个 Turtle ,一个 Lion 和一个海豚。然后我将演示一只乌龟是如何 OceanAnimal 和 LandAnimal ,狮子只是 LandAnimal ,以及海豚只是 OceanAnimal 。我将通过解释什么是鸭子打字来结束。

To answer your question directly I'll use functions to create a Turtle, a Lion and a Dolphin. Then I'll demonstrate how a turtle is an OceanAnimal and a LandAnimal, how a lion is only a LandAnimal, and how a dolphin is only an OceanAnimal. I'll conclude by explaining what is duck typing.

首先让我们为 OceanAnimal 创建构造函数:

First let's create the constructor for an 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 + ", the " + this.type +
               ", and I just walked " + n + " meters.";
    };
}

好的。所以现在让我们为 Turtle 创建构造函数:

Alright. So now let's create the constructor for a Turtle:

Turtle.prototype.type = "turtle";

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

这里发生了什么?好的,我们希望 Turtle 继承 OceanAnimal 和 LandAnimal 。所以我们调用 LandAnimal.call(this)和 OceanAnimal.call(this)。通过这种方式,我们将 OceanAnimal 和 LandAnimal 构造函数用作的。因此 Turtle 继承自 OceanAnimal 和 LandAnimal 而实际上并没有成为类型 OceanAnimal 或 LandAnimal 。

What's happening here? Okay, we want Turtle to inherit from both OceanAnimal and LandAnimal. So we're calling LandAnimal.call(this) and OceanAnimal.call(this). In this way we're using the OceanAnimal and LandAnimal constructors as mixins. Thus Turtle inherits from both OceanAnimal and LandAnimal without actually becoming of type OceanAnimal or LandAnimal.

另一件事是请注意,我们在 Turtle c c>上设置类型属性而不是在里面。这是因为所有海龟的类型都是相同的。因此它是共享的。另一方面,每只乌龟的名称可能会有所不同,因此它在构造函数中设置。

Another thing to notice is that we're setting the type property on the prototype of Turtle instead of inside it. This is because type is the same for all turtles. Thus it's shared. The name of each turtle on the other hand may vary and hence it's set inside the constructor.

现在让我们同样为 Lion 创建构造函数:

Now let's similarly create the constructor for a Lion:

Lion.prototype.type = "lion";

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

由于 Lion 是a LandAnimal 我们只混合 LandAnimal 构造函数。

Since Lion is a LandAnimal we only mix in the LandAnimal constructor.

类似地,对于 Dolphin :

Dolphin.prototype.type = "dolphin";

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

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

Now that we have created all the constructors let's create a turtle, a lion and a dolphin:

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

Awww,现在让我们免费设置:

Awww, now let's set them free:

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

哈哈。那很有趣。就个人而言,我最喜欢yoyo。

Haha. That was fun. Personally I love yoyo the most.

好的,那么什么是打字?我们知道yoyo是 OceanAnimal 和 LandAnimal 。但是,如果我们执行 yoyo instanceof OceanAnimal 或 yoyo instanceof LandAnimal ,则返回 false 。什么?

Okay, so what's duck typing? We know that yoyo is an OceanAnimal and a LandAnimal. However if we do yoyo instanceof OceanAnimal or yoyo instanceof LandAnimal then it returns false. What?


  • 你:愚蠢的JavaScript。 海龟是 OceanAnimal 和 LandAnimal !

  • JavaScript:不是我站在哪里。我所知道的是它是一个海龟。

  • 你:但是如果它游了,那就是 OceanAnimal ,如果它走了,那么它是 LandAnimal 。

  • You: Stupid JavaScript. A Turtle is an OceanAnimal and a LandAnimal!
  • JavaScript: Not from where I'm standing. All I know is that it's a Turtle.
  • You: But if it swims then it's an OceanAnimal, and if it walks then it's a LandAnimal.

因为JavaScript是这样的派对,所以我们必须创建自己的测试来检查对象是否是 OceanAnimal ,如果是a LandAnimal 。

So since JavaScript is such a party pooper we'll have to create our own test to check if an object is an OceanAnimal and if it's a LandAnimal.

让我们从 OceanAnimal 开始:

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 instanceof LandAnimal ;这两个函数都会为我们心爱的yoyo返回 true 。 Yay!

So now we can use isOceanAnimal(yoyo) instead of yoyo instanceof OceanAnimal, and isLandAnimal(yoyo) instead of yoyo instanceof LandAnimal; and both these functions will return true for our beloved yoyo. Yay!

这是一个用JavaScript输入鸭子的简单例子。总结:

This is a simple example of duck typing in JavaScript. To conclude:

同样:

编辑:您可以在此处查看以上代码:

You can see the above code in action here: http://jsfiddle.net/aaditmshah/X9M4G/

这篇关于Javascript Duck打字的例子?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-16 20:37