gpt4 book ai didi

javascript - Javascript鸭子打字的例子?

转载 作者:可可西里 更新时间:2023-11-01 02:50:20 26 4
gpt4 key购买 nike

一些程序员建议不要在 Javascript 中使用伪经典继承,但建议使用鸭子类型并为每个对象提供一组功能。

有没有一个很好的例子来说明如何做到这一点?我在下面有一个示例,但它一次只分配一个功能。我们可以给一个对象分配一整组方法吗,比如我们可以设置一个OceanAnimal的原型(prototype)吗?可以“游泳”、“潜水”和“上升”,LandAnimal 的原型(prototype)对于“run”、“walk”和“jump”,让一个对象从其中一个或两个继承? (所以鱼对象可以继承或获得 OceanAnimal 的功能,而乌龟可以同时获得 OceanAnimalLandAnimal 的功能?)

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 中的函数是通用的。它们可以用作 subroutines , methods , constructors , namespaces , modules , 以及更多。

人们反对在 JavaScript 中使用伪经典继承的原因是因为它隐藏了 JavaScript 的真正威力。如果不比对象更具表现力,函数也同样具有表现力。 Alonzo Church 已经证明了这一点谁的工作,Lambda Calculus , 是 Turing Complete .

为了直接回答您的问题,我将使用函数来创建 Turtle , 一个 LionDolphin .然后我将演示乌龟是如何成为 OceanAnimal 的。和 LandAnimal , 狮子怎么只有LandAnimal ,以及海豚如何只是 OceanAnimal .最后,我将解释什么是鸭式打字。

首先让我们为 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 创建构造函数。 :
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) .通过这种方式,我们使用 OceanAnimalLandAnimal构造函数为 mixins .因此 Turtle继承自 OceanAnimalLandAnimal没有真正成为 OceanAnimal 类型或 LandAnimal .

需要注意的另一件事是,我们正在设置 type prototype 上的属性(property)的 Turtle而不是在里面。这是因为 type所有海龟都一样。因此它是共享的。 name另一方面,每只海龟的值可能会有所不同,因此它是在构造函数中设置的。

现在让我们为 Lion 创建类似的构造函数。 :
Lion.prototype.type = "lion";

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

由于 LionLandAnimal我们只混入 LandAnimal构造函数。

对于 Dolphin 也是如此:
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 是一个 OceanAnimalLandAnimal .但是,如果我们这样做 yoyo instanceof OceanAnimalyoyo instanceof LandAnimal然后返回 false .什么?
  • 你:愚蠢的 JavaScript。一个 TurtleOceanAnimalLandAnimal !
  • JavaScript: 不是从我站的地方。我只知道这是一个 Turtle .
  • 你:但如果它会游泳,那么它就是 OceanAnimal ,如果它会走路,那么它就是 LandAnimal .

  • 因此,由于 JavaScript 是个大杂烩,我们必须创建自己的测试来检查对象是否为 OceanAnimal。如果是 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 ;这两个函数都将返回 true为了我们亲爱的悠悠。耶!

    这是一个在 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/

    关于javascript - Javascript鸭子打字的例子?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12762550/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com