it-swarm.com.de

Ein Objekt in Javascript erweitern

Ich verwandle mich derzeit von Java in Javascript und es ist etwas schwierig für mich, herauszufinden, wie ich Objekte so erweitern kann, wie ich es möchte.

Ich habe gesehen, dass mehrere Personen im Internet eine Methode namens "extend on object" verwenden. Der Code sieht so aus:

var Person = {
   name : 'Blank',
   age  : 22
}

var Robot = Person.extend({
   name : 'Robo',
   age  : 4
)}

var robot = new Robot();
alert(robot.name); //Should return 'Robo'

Weiß jemand, wie das funktioniert? Ich habe gehört, dass Sie schreiben müssen 

Object.prototype.extend = function(...);

Aber ich weiß nicht, wie ich dieses System zum Laufen bringen kann. Falls dies nicht möglich ist, zeigen Sie mir bitte eine andere Alternative, die ein Objekt erweitert.

137
Wituz

Bearbeiten :
Bevor Sie den Code verwenden, überprüfen Sie bitte die Kommentare von user2491400, die über die Nebenwirkungen einer einfachen Zuordnung zu prototype berichten.

Ursprüngliche Antwort:

Sie möchten das Prototypobjekt von Person "erben":

var Person = function(name){
  this.name = name;
  this.type = 'human';
}

Person.prototype.info = function(){
  console.log("Name:", this.name, "Type:", this.type);
}

var Robot = function(name){
  Person.apply(this,arguments)
  this.name = name;
  this.type = 'robot';
}

Robot.prototype = Person.prototype;        // Set prototype to Person's
Robot.prototype.constructor = Robot;   // Set constructor back to Robot

person = new Person("Bob");
robot = new Robot("Boutros");

person.info();
// Name: Bob Type: human

robot.info();
// Name: Boutros Type: robot
186
osahyoun

Welt ohne das "neue" Stichwort.

Und einfachere Syntax mit Object.create ().

Ich bin im Camp, der meint, Javascript sollte versuchen, ohne "neues" zu leben. Es ist eine klassenlose Sprache, es braucht keine Konstruktoren. Sie erstellen einfach Objekte und erweitern oder verwandeln sie. Zugegeben, es gibt Fallstricke, aber das ist viel mächtiger und einfacher:

// base `Person` prototype
const Person = {
   name : '',
   age  : 22,
   type : 'human',
   greet() {
       console.log('Hi, my name is ' + this.name + ' and I am a ' + this.type + '.' )
   }
}

// create an instance of `Person`:
const skywalker = Object.create(Person)
skywalker.name = 'Anakin Skywalker'
skywalker.greet() // 'Hi, my name is Anakin Skywalker and I am a human.'

Erweiterung des Basisprototyps

// create a `Robot` prototype by extending the `Person` prototype:
const Robot = Object.create(Person)
Robot.type = 'robot'
Robot.variant = '' // add properties for Robot prototype

// Robots speak in binaries, so we need a different greet function:
Robot.greet = function() { //some function to convert strings to binary }

Eine Ebene tiefer

// create a new instance `Robot`
const Astromech = Object.create(Robot)
Astromech.variant = 'astromech'

const r2d2 = Object.create(Astromech)
r2d2.name = 'R2D2'
r2d2.greet() // '0000111010101011100111....'

// morphing the `Robot` object doesn't affect `Person` prototypes
skywalker.greet() // 'Hi, my name is Anakin Skywalker and I am a human.'

Lesen Sie weiter

** Update 3 Oct 18. Übernehmen Sie die ES6-Syntax und verwenden Sie const und let. Beispiel hinzugefügt, um zu zeigen, wie Eigenschaften unveränderlich gemacht werden.

** Update vom 22. Januar 17. Enthaltenes ES6-Objekt Object.assign ().

Wie Sie sehen, erfordert die Zuweisung mehrere Anweisungen. Mit ES6 können Sie die Zuweisung mit der Methode #assign verkürzen. (Für Polyfill bei älteren Browsern siehe MDN auf ES6 .)

//instead of this
const Robot = Object.create(Person)
Robot.name = "Robot"
Robot.madeOf = "metal"
Robot.powerConsumption_kW = 5

//you can do this
const Robot = Object.create(Person)
Object.assign(Robot, {
    name: "Robot",
    madeOf: "metal",
    powerConsumption_kWh: 5,
    fullCharge_kWh: 10,
    currentCharge_kWh: 5
})

//attach some methods unique to Robot prototype.
Robot.charge = function(kWh) {
    let self = this
    this.currentCharge_kWh = Math.min(self.fullCharge_kWh, self.currentCharge_kWh + kWh)
    var percentageCharged = this.currentCharge_kWh / this.fullCharge_kWh * 100
    console.log(this.name + (percentageCharged === 100) ? ' is fully charged.' : ' is ' + percentageCharged +'% charged.')
}

Robot.charge(5) // outputs "Robot is fully charged."

Sie können auch das zweite Argument von Object.create () a.k.a propertiesObject verwenden, das ich etwas zu lang finde. Der einzige Grund für die Verwendung von #assign besteht darin, dass Sie mehr Kontrolle über die Werte benötigen, d. H. Schreibbarkeit/Konfigurierbarkeit usw. ... Beachten Sie, dass Robot ausschließlich aus Metall bestehen muss.

const Robot = Object.create(Person, {
    madeOf: { 
        value: "metal",
        writable: false,
        configurable: false,
        enumerable: true
    },
    powerConsumption: {
        value: "5kWh",
        writable: true,
        configurable: true,
        enumerable: true   
    }
})

Und alle Prototypen von Robot können nicht aus etwas anderem bestehen.

const polymerRobot = Object.create(Robot)

polymerRobot.madeOf = 'polymer'

console.log(polymerRobot.madeOf) // outputs 'metal'

In diesem Muster gibt es striche Muster, die wahrscheinlich "klassisch geschulte" Programmierer auslösen. Trotzdem finde ich dieses Muster viel lesbarer.

78
Calvintwr

Wenn Sie noch keine Möglichkeit gefunden haben, fügen Sie mithilfe der assoziativen Eigenschaft von JavaScript-Objekten eine Erweiterungsfunktion zum Object.prototype hinzu (siehe unten).

Object.prototype.extend = function(obj) {
   for (var i in obj) {
      if (obj.hasOwnProperty(i)) {
         this[i] = obj[i];
      }
   }
};

Sie können diese Funktion dann wie unten gezeigt verwenden.

var o = { member: "some member" };
var x = { extension: "some extension" };

o.extend(x);
51
tomilay

Anderer Ansatz: Object.create

In der Antwort von @osahyoun finde ich Folgendes als einen besseren und effizienteren Weg, um das Prototypobjekt von Person zu "erben": 

function Person(name){
    this.name = name;
    this.type = 'human';
}

Person.prototype.info = function(){
    console.log("Name:", this.name, "Type:", this.type);
}

function Robot(name){
    Person.call(this, name)
    this.type = 'robot';
}

// Set Robot's prototype to Person's prototype by
// creating a new object that inherits from Person.prototype,
// and assigning it to Robot.prototype
Robot.prototype = Object.create(Person.prototype);

// Set constructor back to Robot
Robot.prototype.constructor = Robot;

Neue Instanzen erstellen:

var person = new Person("Bob");
var robot = new Robot("Boutros");

person.info(); // Name: Bob Type: human
robot.info();  // Name: Boutros Type: robot

Jetzt mit Object.create :

Person.prototype.constructor !== Robot

Überprüfen Sie auch die Dokumentation zu MDN .

27
Lior Elrom

Und noch ein Jahr später kann ich Ihnen sagen, dass es eine weitere schöne Antwort von Nizza gibt.

Wenn Ihnen Prototyping nicht gefällt, um Objekte/Klassen zu erweitern, sollten Sie Folgendes beachten: https://github.com/haroldiedema/joii

Schneller Beispielcode für Möglichkeiten (und viele mehr):

var Person = Class({

    username: 'John',
    role: 'Employee',

    __construct: function(name, role) {
        this.username = name;
        this.role = role;
    },

    getNameAndRole: function() {
        return this.username + ' - ' + this.role;
    }

});

var Manager = Class({ extends: Person }, {

  __construct: function(name)
  {
      this.super('__construct', name, 'Manager');
  }

});

var m = new Manager('John');
console.log(m.getNameAndRole()); // Prints: "John - Manager"
18
Harold

In ES6 können Sie einen Spread-Operator wie verwenden

var mergedObj = { ...Obj1, ...Obj2 };

Beachten Sie, dass Object.assign () Setter auslöst, Spread-Syntax jedoch nicht.

Weitere Informationen finden Sie unter dem Link MDN -Spread Syntax


Alte Antwort:

In ES6 gibt es Object.assign zum Kopieren von Eigenschaftswerten. Verwenden {} als erster Parameter, wenn Sie das Zielobjekt nicht ändern möchten (der erste übergebene Parameter).

var mergedObj = Object.assign({}, Obj1, Obj2);

Weitere Informationen finden Sie unter dem Link MDN - Object.assign ()

Falls Sie eine Polyfill für ES5 benötigen, bietet der Link diese ebenfalls an. :)

16
KrIsHnA

Vielleicht möchten Sie die Helper-Bibliothek wie underscore.js verwenden, die ihre eigene Implementierung von extend() hat.

Und es ist auch eine gute Möglichkeit, den Quellcode zu lernen. Die kommentierte Quellcodeseite ist sehr nützlich.

8
250R

Mozilla-Objekt "kündigt" an, das sich ab ECMAScript 6.0 erstreckt:

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes/extends

HINWEIS: Dies ist eine experimentelle Technologie, die Teil des Vorschlags von ECMAScript 6 (Harmony) ist.

class Square extends Polygon {
  constructor(length) {
    // Here, it calls the parent class' constructor with lengths
    // provided for the Polygon's width and height
    super(length, length);
    // Note: In derived classes, super() must be called before you
    // can use 'this'. Leaving this out will cause a reference error.
    this.name = 'Square';
  }

  get area() {
    return this.height * this.width;
  }

  set area(value) {
    this.area = value;     } 
}

Diese Technologie ist in Gecko (Google Chrome/Firefox) - 03/2015 verfügbar.

6
Niek Vandael

Personen, die immer noch um die einfache und beste Vorgehensweise kämpfen, können SieSpread Syntaxverwenden, um das Objekt zu erweitern.

var person1 = {
      name: "Blank",
      age: 22
    };

var person2 = {
      name: "Robo",
      age: 4,
      height: '6 feet'
    };
// spread syntax
let newObj = { ...person1, ...person2 };
console.log(newObj.height);

Hinweis: Denken Sie daran, dass die Eigenschaft am weitesten rechts ist und die Priorität hat. In diesem Beispiel befindet sich person2 auf der rechten Seite, sodass newObj den Namen Robo enthält.

5
Ali Shahbaz

In der Mehrheit des Projekts gibt es einige Implementierungen der Objekterweiterung: Unterstrich, Jquery, Lodge: extend.

Es gibt auch reine Javascript-Implementierung, die Teil von ECMAscript 6 ist: Object.assign: https://developer.mozilla.org/en-US/docs/Web/JavaScript/ Referenz/Global_Objects/Objekt/Zuweisen

3
Function.prototype.extends=function(ParentClass) {
    this.prototype = new ParentClass();
    this.prototype.constructor = this;
}

Dann:

function Person() {
    this.name = "anonym"
    this.skills = ["abc"];
}
Person.prototype.profile = function() {
    return this.skills.length // 1
};

function Student() {} //well extends fom Person Class
Student.extends(Person)

var s1 = new Student();
s1.skills.Push("")
s1.profile() // 2

Update 01/2017:

Bitte ignorieren Sie meine Antwort von 2015, da Javascript jetzt das extends-Schlüsselwort seit ES6 unterstützt (Ecmasctipt6).

- ES6:

class Person {
   constructor() {
     this.name = "anonym"
     this.skills = ["abc"];
   }

   profile() {
    return this.skills.length // 1
   }

}

Person.MAX_SKILLS = 10;
class Student extends Person {


} //well extends from Person Class

//-----------------
var s1 = new Student();
s1.skills.Push("")
s1.profile() // 2

- ES7:

class Person {
    static MAX_SKILLS = 10;
    name = "anonym"
    skills = ["abc"];

    profile() {
      return this.skills.length // 1
    }

}
class Student extends Person {


} //well extends from Person Class

//-----------------
var s1 = new Student();
s1.skills.Push("")
s1.profile() // 2
2
Abdennour TOUMI

BITTE GRÜNDE HINZUFÜGEN

  • Sie müssen keine externe Bibliothek zum Erweitern verwenden

  • In JavaScript ist alles ein Objekt (mit Ausnahme der drei primitiven Datentypen .__, und sogar sie werden bei Bedarf automatisch mit -Objekten umbrochen). Darüber hinaus sind alle Objekte veränderbar.

Klassenperson in JavaScript

function Person(name, age) {
    this.name = name;
    this.age = age;
}
Person.prototype = {
    getName: function() {
        return this.name;
    },
    getAge: function() {
        return this.age;
    }
}

/* Instantiate the class. */
var alice = new Person('Alice', 93);
var bill = new Person('Bill', 30);

Ändern Sie eine bestimmte Instanz/ein Objekt .

alice.displayGreeting = function() 
{
    alert(this.getGreeting());
}

Ändern Sie die Klasse

Person.prototype.getGreeting = function() 
{
    return 'Hi ' + this.getName() + '!';
};

Oder einfach sagen: JSON und OBJECT erweitern sind beide gleich

var k = {
    name : 'jack',
    age : 30
}

k.gender = 'male'; /*object or json k got extended with new property gender*/

dank Ross schadet Dustin Diaz

0
vijay

Sie können dies einfach tun, indem Sie Folgendes verwenden:

Object.prototype.extend = function(object) {
  // loop through object 
  for (var i in object) {
    // check if the extended object has that property
    if (object.hasOwnProperty(i)) {
      // mow check if the child is also and object so we go through it recursively
      if (typeof this[i] == "object" && this.hasOwnProperty(i) && this[i] != null) {
        this[i].extend(object[i]);
      } else {
        this[i] = object[i];
      }
    }
  }
  return this;
};

update: Ich habe nach this[i] != null gesucht, da null ein Objekt ist

Dann benutze es wie:

var options = {
      foo: 'bar',
      baz: 'dar'
    }

    var defaults = {
      foo: false,
      baz: 'car',
      nat: 0
    }

defaults.extend(options);

Dies führt gut zu:

// defaults will now be
{
  foo: 'bar',
  baz: 'dar',
  nat: 0
}
0
Mustafa Dwekat

Zusammenfassung:

Javascript verwendet einen Mechanismus, der als prototypale Vererbung bezeichnet wird. Beim Nachschlagen einer Eigenschaft für ein Objekt wird prototypische Vererbung verwendet. Wenn wir Eigenschaften in Javascript erweitern, übernehmen wir diese Eigenschaften von einem tatsächlichen Objekt. Es funktioniert auf folgende Weise:

  1. Wenn eine Objekteigenschaft angefordert wird (z. B. myObj.foo oder myObj['foo']), sucht die JS-Engine zuerst im Objekt selbst nach dieser Eigenschaft
  2. Wenn diese Eigenschaft nicht auf dem Objekt selbst gefunden wird, wird die Prototypkette erklimmen das Prototypobjekt betrachten. Wenn diese Eigenschaft auch hier nicht gefunden wird, steigt sie die Prototypkette an, bis die Eigenschaft gefunden wird. Wenn die Eigenschaft nicht gefunden wird, wird ein Referenzfehler ausgegeben.

Wenn wir ein Objekt in Javascript erweitern möchten, können wir dieses Objekt einfach in der Prototypkette verknüpfen. Es gibt zahlreiche Möglichkeiten, dies zu erreichen. Ich werde zwei häufig verwendete Methoden beschreiben.

Beispiele:

1. Object.create()

Object.create() ist eine Funktion, die ein Objekt als Argument verwendet und ein neues Objekt erstellt. Das Objekt, das als Argument übergeben wurde, ist der Prototyp des neu erstellten Objekts. Zum Beispiel:

// prototype of the dog
const dogPrototype = {
  woof: function () { console.log('woof'); }
}

// create 2 dog objects, pass prototype as an argument
const fluffy = Object.create(dogPrototype);
const notFluffy = Object.create(dogPrototype);

// both newly created object inherit the woof 
// function from the dogPrototype
fluffy.woof();
notFluffy.woof();

2. Explizite Einstellung der Prototypeneigenschaft

Wenn Sie Objekte mit Konstruktorfunktionen erstellen, können Sie der Prototyp-Objekteigenschaft Eigenschaften hinzufügen. Objekte, die bei Verwendung des Schlüsselworts new von einer Konstruktorfunktion erstellt werden, haben ihren Prototyp auf den Prototyp der Konstruktorfunktion gesetzt. Zum Beispiel:

// Constructor function object
function Dog (name) {
   name = this.name;
}

// Functions are just objects
// All functions have a prototype property
// When a function is used as a constructor (with the new keyword)
// The newly created object will have the consturctor function's
// prototype as its prototype property
Dog.prototype.woof = function () {
  console.log('woof');
}

// create a new dog instance
const fluffy = new Dog('fluffyGoodBoyyyyy');
// fluffy inherits the woof method
fluffy.woof();

// can check the prototype in the following manner
console.log(Object.getPrototypeOf(fluffy));

0