在 Javascript 中使用组件

发布于 2024-10-31 13:00:40 字数 423 浏览 0 评论 0原文

我对 Javascript 比较陌生。我想知道它是否像 Python 一样支持组件和对象。如果是这样,语法会是什么样子?

例如,我知道一个对象看起来像这样:

function Foo(a, b) {
    this.a = a;
    this.b = b;
}

现在,有没有办法声明一些组件,选择其中一个,然后将其添加到对象中?例如,假设我有一个对象 Item。我可以声明一些不同的组件,例如武器、魔法、传奇等,然后将它们添加到对象中吗?使用这种方法,我最终可能会得到一件魔法武器,或者一件传奇物品,甚至一件传奇魔法武器。

我想过为此使用养育方式,但对于我想做的事情来说,这似乎相当有限。例如,我的继承体系看起来像物品/武器或物品/传奇,所以我不能拥有传奇武器。

那么,Javascript 中可以使用组件吗?

I'm relatively new to Javascript. I was wondering if it supports components and objects like Python does. If it does, what would the syntax look like?

For instance, I know an object look like this:

function Foo(a, b) {
    this.a = a;
    this.b = b;
}

Now, is there a way to declare some components, pick one of those, and add it to the object? For instance, let's say I have a object Item. Could I declare some different components, such as Weapon, Magical, Legendary, etc. and them add them to the object? Using this approach I could end up with a Magical Weapon, or a Legendary Item, or even a Legendary Magical Weapon.

I thought about using parenting for this but for what I want to do, it seems like that would be rather limited. For instance, my heirarchy would look like Item/Weapon or Item/Legendary, so I couldn't have a Legendary Weapon.

So, are components possible in Javascript?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

乙白 2024-11-07 13:00:41

javascript 中的对象如下所示:

var Foo = {
    a: null,
    b: null,

    init: function(a,b){
        this.a = a;
        this.b = b;
    }

}
//call the init:
Foo.init(12,34);

几乎与问题中的对象相同。

并且这个对象是可扩展的

an object in javascript looks like this:

var Foo = {
    a: null,
    b: null,

    init: function(a,b){
        this.a = a;
        this.b = b;
    }

}
//call the init:
Foo.init(12,34);

almost the same as you have in the question.

And this object is extendable

遥远的绿洲 2024-11-07 13:00:41

您的代码示例是一个 Function 对象,该对象旨在用作构造函数,即使用 new 关键字调用它,它返回一个具有 的对象实例。 code>a 属性和 b 属性(以及其他继承的属性)。

像 JavaScript 中的所有其他对象一样,Function 对象继承自 Object

通常,对象是使用对象字面量语法创建的,即 var x = { a: 'a', b: 'b' };尽管它们也可以通过使用带有 Object 的 new 关键字来创建。

看起来你的问题是指 JavaScript 的继承。嗯,执行继承的方法有很多种。一个例子是

function A() { }

function B() { }
B.prototype = new A;

这里 AB 都是构造函数。函数有一个 prototype 属性,它是一个对象,可以包含可由该函数构造的所有对象实例共享的成员。我们将构造函数 A 返回的对象实例分配给 B 的原型,从而为 B 提供 B 实例上可用的所有成员。代码>A。这只是在 JavaScript 中执行继承的一种方法。

Mozilla 开发人员中心有关对象模型的文章< /a> 值得一读。

you code example is a Function object which is intended to be used as a constructor function i.e. call it with the new keyword and it returns an instance of an object that has an a property and a b property (amongst other inherited properties).

Function objects inherit from Object like all other objects in JavaScript.

Usually, objects are created using object literal syntax, i.e. var x = { a: 'a', b: 'b' }; although they can also be created by using the new keyword with Object.

It looks like your question is referring to inheritance with JavaScript. Well, there are many ways to perform inheritance. One example is

function A() { }

function B() { }
B.prototype = new A;

Here both A and B are constructor functions. Functions have a prototype property which is an object and can contain members that can be shared by all object instances constructed by the function. We assign an instance of an object returned by the constructor function A to B's prototype, giving B all members available on an instance of A. This is just one way to perform inheritance in JavaScript.

The Mozilla Developer Center article on the Object Model is worth a read.

我三岁 2024-11-07 13:00:40

您所描述的“组件”通常称为类。您所描述的“养育”通常称为继承。您对类层次结构很了解:)

好的,您的基类位于 Item 中。该物品将具有游戏世界中所有物品都必须具有的基本属性。游戏世界中的所有对象都将从 Item 继承。

武器是一个物品。 MagicalItem 是一个项目。 LegendaryItem 是一个项目。这三个类都是Item的子类。

当您想要一个 LegendaryMagicalWeaponItem 时,事情会变得有点棘手。这就是你的问题的本质:JavaScript 中是否可以实现多重继承?

用 Boondock Saints 的话来说,除非您绝对、肯定地确定您需要多重继承,否则您不需要多重继承。为什么?它很快就会导致并发症。例如,如果两个超类具有同名的方法或属性怎么办?如果它们继承自两个不同的基类,并且这些类之一导致名称冲突怎么办?你可以看到这是怎么回事。

幸运的是,JavaScript 和 Python 一样,是一种非常灵活的语言。您不必被迫使用多重继承甚至接口来泛化异构对象之间的行为。

假设 MagicalItem 有一个 mana 属性,而 LegendaryItem 有一个 legacy() 方法。假设武器对象有损坏。假设 Item 具有重要的物理属性和一堆物理方法;它显然是“占主导地位”的超类。没有什么可以阻止你这样做:

// Base classes
function Item() {
   // some default values...
}
Item.prototype.physics = function (t) {/* physics stuff */}

function Magical(mana) {
  this.mana = mana;
}
function Weapon(damage) {
  this.damage = damage;
}
function Legendary(legacy) {
  this.legacy = function () {return legacy;};
}

// Actual world item class
function MyLegendaryMagicalSword(x,y) {
  this.x = x;
  this.y = y;
  Weapon.call(this, MyLegendaryMagicalSword.DAMAGE);
  Legendary.call(this, MyLegendaryMagicalSword.LORE);
  Magical.call(this, MyLegendaryMagicalSword.START_MANA);
}
// actual prototypal inheritance
MyLegendaryMagicalSword.prototype = new Item();
// class attributes
MyLegendaryMagicalSword.DAMAGE = 1000;
MyLegendaryMagicalSword.START_MANA = 10;
MyLegendaryMagicalSword.LORE = "An old sword.";

// Sword instance
var sword = new MyLegendaryMagicalSword(0, 0);
sword.physics(0);
sword.mana;
sword.legacy();
// etc

// probe object for supported interface
if (sword.hasOwnProperty("damage")) {
   // it's a weapon...
}

这是一种卑鄙而肮脏的方式来做你所描述的事情。

> sword
{ x: 0,
  y: 0,
  damage: 1000,
  legacy: [Function],
  mana: 10 }

What you describe as a 'component' is more commonly called a class. What you describe as 'parenting' is more commonly called inheritance. You are spot on about the class hierarchy :)

Ok, so your base class in an Item. This item will have the basic attributes which all items in your game world must have. All objects in your game world will inherit from Item.

A Weapon is an Item. A MagicalItem is an Item. A LegendaryItem is an item. These three classes are all subclasses of Item.

Things get a little bit more tricky when you want a LegendaryMagicalWeaponItem. This is the essence of your question: Is multiple inheritance possible in JavaScript?

To paraphrase the Boondock Saints, you do not want multiple inheritance unless you are absolutely, positively sure that you need it. Why? It quickly leads to complications. For example, what if two superclasses have a method or an attribute with the same name? What if they inherit from two different base classes, and one of those classes causes a name collision? You can see where this is going.

Fortunately, JavaScript, like Python, is a very flexible language. You are not forced to use multiple inheritance or even interfaces to generalise behaviour across heterogeneous objects.

Let's say MagicalItem has a mana property and LegendaryItem has a legacy() method. Let's say a weapon object has a damage. Let's say Item has important physical attributes and a bunch of physics methods; it is clearly the 'dominant' superclass. There is nothing stopping you from doing this:

// Base classes
function Item() {
   // some default values...
}
Item.prototype.physics = function (t) {/* physics stuff */}

function Magical(mana) {
  this.mana = mana;
}
function Weapon(damage) {
  this.damage = damage;
}
function Legendary(legacy) {
  this.legacy = function () {return legacy;};
}

// Actual world item class
function MyLegendaryMagicalSword(x,y) {
  this.x = x;
  this.y = y;
  Weapon.call(this, MyLegendaryMagicalSword.DAMAGE);
  Legendary.call(this, MyLegendaryMagicalSword.LORE);
  Magical.call(this, MyLegendaryMagicalSword.START_MANA);
}
// actual prototypal inheritance
MyLegendaryMagicalSword.prototype = new Item();
// class attributes
MyLegendaryMagicalSword.DAMAGE = 1000;
MyLegendaryMagicalSword.START_MANA = 10;
MyLegendaryMagicalSword.LORE = "An old sword.";

// Sword instance
var sword = new MyLegendaryMagicalSword(0, 0);
sword.physics(0);
sword.mana;
sword.legacy();
// etc

// probe object for supported interface
if (sword.hasOwnProperty("damage")) {
   // it's a weapon...
}

This is a down and dirty way to do what you describe.

> sword
{ x: 0,
  y: 0,
  damage: 1000,
  legacy: [Function],
  mana: 10 }
梦途 2024-11-07 13:00:40

我不知道你所说的组件是什么意思。这个词太笼统了。在Delphi中,组件是一个不可见的代码模块,它为应用程序引入了一些特殊的功能。 “计时器”就是这样一个组件示例(在 Delphi 中)。

从你的描述猜测,你似乎想要动态添加属性?还是与超载有关?

在后一种情况下,您不能通过设计来做到这一点,因为它解除了您提到的限制。

示例(混合):

function mixItems(weapon,legend){
    return {
        "damage":legend.damage+weapon.damage,
        "name":legend.name+"' "+weapon.name
    };
}

var weapon={ "damage":45, "name":"sword"};

var legend={ "name":"Goliath", "damage":34 };

var LegendaryWeapon = mixItems(weapon,legend);

console.log( LegendaryWeapon );
// output:- name: "Goliath's sword", damage: 79

示例(扩展):

function clone(old){ // non-deep cloning function
    var res={};
    for(i in old)
        res[i]=old[i];
    return res;
}

var sword = {
    "damage":50
    "hit": function(){ // returns the percentage hit chance
        return Math.round(Math.random()*100);
    }
};

var bigsword=clone(sword);

bigsword.damage=60;
bigsword.hit=function(){ // returns the percentage hit chance
    return Math.round(Math.random()*80)+20;
};

I have no idea what you mean by components. The term is too generalized. In Delphi, a component is a non-visible code module which introduces some special functionality to the application. A "timer" is one such example of a component (in Delphi).

Guessing from your description, you seem to want to add properties dynamically? Or is it about overloading?

In the latter case, you can't do this by design, as in, it lifts the limitations you mentioned.

Example (mixing):

function mixItems(weapon,legend){
    return {
        "damage":legend.damage+weapon.damage,
        "name":legend.name+"' "+weapon.name
    };
}

var weapon={ "damage":45, "name":"sword"};

var legend={ "name":"Goliath", "damage":34 };

var LegendaryWeapon = mixItems(weapon,legend);

console.log( LegendaryWeapon );
// output:- name: "Goliath's sword", damage: 79

Example (extending):

function clone(old){ // non-deep cloning function
    var res={};
    for(i in old)
        res[i]=old[i];
    return res;
}

var sword = {
    "damage":50
    "hit": function(){ // returns the percentage hit chance
        return Math.round(Math.random()*100);
    }
};

var bigsword=clone(sword);

bigsword.damage=60;
bigsword.hit=function(){ // returns the percentage hit chance
    return Math.round(Math.random()*80)+20;
};
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文