Методы JavaScript переопределить



допустим, у вас есть код ниже:



function A() {
function modify(){
x = 300;
y = 400;
}
var c = new C();
}

function B() {
function modify(){
x = 3000;
y = 4000;
}
var c = new C();
}


C = function () {
var x = 10;
var y = 20;

function modify() {
x = 30;
y = 40;
};

modify();
alert("The sum is: " + (x+y));
}


теперь вопрос, если есть какой-либо способ, в котором я могу переопределить метод modify из C с методами, которые находятся в A и B. В Java вы бы использовали ключевое слово super, но как вы можете достичь чего-то подобного в JavaScript?

642   7  

7 ответов:

Edit: прошло уже шесть лет с тех пор, как был написан оригинальный ответ, и многое изменилось!

  • если вы используете более новую версию JavaScript, возможно, скомпилированную с помощью такого инструмента, как Бабель вы можете использовать реальные классы.
  • если вы используете конструкторы компонентов типа класса, предоставляемые Угловое или реагировать, вы хотите посмотреть в документах для этой структуры.
  • если вы используете ES5 и делая "поддельные" классы вручную, используя прототипы, ответ ниже по-прежнему так же прав, как и когда-либо.

удачи!


наследование JavaScript выглядит немного иначе, чем Java. Вот как выглядит собственная объектная система JavaScript:

// Create a class
function Vehicle(color){
  this.color = color;
}

// Add an instance method
Vehicle.prototype.go = function(){
  return "Underway in " + this.color;
}

// Add a second class
function Car(color){
  this.color = color;
}

// And declare it is a subclass of the first
Car.prototype = new Vehicle();

// Override the instance method
Car.prototype.go = function(){
  return Vehicle.prototype.go.call(this) + " car"
}

// Create some instances and see the overridden behavior.
var v = new Vehicle("blue");
v.go() // "Underway in blue"

var c = new Car("red");
c.go() // "Underway in red car"

к сожалению, это немного некрасиво и не включает в себя очень хороший способ "супер": вы должны вручную указать, какой метод родительского класса, который вы хотите вызвать. В результате, существуют различные инструменты, чтобы сделать создание классов приятнее. Попробуйте посмотреть на прототип.js, позвоночник.js или аналогичная библиотека, которая включает в себя более приятный синтаксис для выполнения ООП в js.

Так как это топ-хит на Google, я хотел бы дать обновленный ответ.

используя ES6 классы делает наследование и переопределение метода намного проще:

'use strict';

class A {
    speak() {
        console.log("I'm A");
    }
}

class B extends A {
    speak() {
        super.speak();

        console.log("I'm B");
    }
}

var a = new A();
a.speak();
// Output:
// I'm A

var b = new B();
b.speak();
// Output:
// I'm A
// I'm B

The super ключевое слово относится к родительскому классу при использовании в наследующем классе. Кроме того, все методы родительского класса привязаны к экземпляру дочернего, поэтому вам не нужно писать super.method.apply(this);.

что касается совместимости: совместимость с ES6 таблица показывает только самые последние версии основных классов поддержки игроков (в основном). Браузеры V8 имеют их с января этого года (Chrome и Opera), а Firefox, используя движок SpiderMonkey JS, увидит классы в следующем месяце с их официальным выпуском Firefox 45. На мобильной стороне Android по-прежнему не поддерживает эту функцию, в то время как iOS 9, выпущенная пять месяцев назад, имеет частичную поддержку.

к счастью, есть Бабель, библиотека JS для повторная компиляция кода гармонии в код ES5. Классы и множество других интересных функций в ES6 могут сделать ваш код Javascript намного более читаемым и поддерживаемым.

один раз следует избегать эмуляции классического OO и вместо этого использовать прототипический OO. Хорошая библиотека утилит для прототипического OO-это черт.

вместо перезаписи методов и настройки цепочек наследования (всегда следует отдавать предпочтение объектной композиции над объектным наследованием) вы должны объединять повторно используемые функции в Признаки и создавать объекты с ними.

Видео

var modifyA = {
    modify: function() {
        this.x = 300;
        this.y = 400;
    }
};

var modifyB = {
    modify: function() {
        this.x = 3000;
        this.y = 4000;
    }
};

C = function(trait) {
    var o = Object.create(Object.prototype, Trait(trait));

    o.modify();
    console.log("sum : " + (o.x + o.y));

    return o;
}

//C(modifyA);
C(modifyB);

modify () в вашем примере-это частная функция, которая будет доступна только из вашего определения A, B или C. Вам нужно будет объявить его как

this.modify = function(){}

C не имеет ссылки на своих родителей, если вы не передадите его в C. Если C настроен для наследования от A или B, он унаследует свои публичные методы (а не его частные функции, как вы определили modify ()). Как только C наследует методы от своего родителя, вы можете переопределить унаследованные методы.

метод modify() то, что вы вызывали в последнем, вызывается в глобальном контексте если вы хотите переопределить modify() сначала вы должны наследовать A или B.

может быть, вы пытаетесь сделать это:

в этом случае C наследует A

function A() {
    this.modify = function() {
        alert("in A");
    }
}

function B() {
    this.modify = function() {
        alert("in B");
    }
}

C = function() {
    this.modify = function() {
        alert("in C");
    };

    C.prototype.modify(); // you can call this method where you need to call modify of the parent class
}

C.prototype = new A();

нет, если вы не сделаете все переменные "публичными", т. е. не сделаете их членами Function либо напрямую, либо через prototype собственность.

var C = function( ) {
    this.x = 10 , this.y = 20 ;
    this.modify = function( ) {
        this.x = 30 , this.y = 40 ;
        console.log("(!) C >> " + (this.x + this.y) ) ;
    } ;
} ;

var A = function( ) {
    this.modify = function( ) {
       this.x = 300 , this.y = 400 ;
       console.log("(!) A >> " + (this.x + this.y) ) ;
    } ;
} ;
    A.prototype = new C ;

var B = function( ) {
    this.modify = function( ) {
       this.x = 3000 , this.y = 4000 ;
       console.log("(!) B >> " + (this.x + this.y) ) ;
    } ;
} ;


new C( ).modify( ) ;
new A( ).modify( ) ;
new B( ).modify( ) ; 
  • .

    затем, x,y и modify все" публичные " члены, так что назначение другой Function в них

     <name>.prototype.modify = function( ) { /* ... */ }
    

    будет "перекрывать" оригинал Function С таким именем.

    наконец, вызов modify не может быть сделано в Function объявление, потому что неявный вызов "суперкласса" будет выполнен опять же, когда мы устанавливаем предполагаемый "супер-класс" в prototype свойство предполагаемых "подклассов".

    но хорошо, это более или менее, как вы будете делать такие вещи в JavaScript.

    HTH,

    FK

function A() {
    var c = new C();
	c.modify = function(){
		c.x = 123;
		c.y = 333;
	}
	c.sum();
}

function B() {
    var c = new C();
	c.modify = function(){
		c.x = 999;
		c.y = 333;
	}
	c.sum();
}


C = function () {
   this.x = 10;
   this.y = 20;

   this.modify = function() {
      this.x = 30;
      this.y = 40;
   };
   
   this.sum = function(){
	this.modify();
	console.log("The sum is: " + (this.x+this.y));
   }
}

A();
B();

Comments

    Ничего не найдено.