开发者

Using components in Javascript

开发者 https://www.devze.com 2023-02-24 02:51 出处:网络
I\'m relatively new to Javascript. I was wondering if it suppor开发者_运维百科ts components and objects like Python does. If it does, what would the syntax look like?

I'm relatively new to Javascript. I was wondering if it suppor开发者_运维百科ts 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?


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 }


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;
};


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


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.

0

精彩评论

暂无评论...
验证码 换一张
取 消