JavaScript наследование Prototypal?

Один из способов - использовать JOptionPane.showInputDialog . Приложение «останавливается» с помощью модального диалога, и вы очень легко получаете его ввод.

Пример:

//returns null if user closes the dialog.
String answer = JOptionPane.showInputDialog("What is your first name?");

16
задан Cœur 6 September 2018 в 03:14
поделиться

4 ответа

1) Почему, если все новые объекты содержат ссылку на прототип функции создателя, fido.prototype не определен?

Все новые объекты действительно содержат ссылку на прототип, который присутствовал на их конструкторе во время конструкции. Однако имя свойства, используемое для хранения этой ссылки, не prototype поскольку это находится на самой функции конструктора. Некоторые реализации JavaScript действительно предоставляют доступ к этому 'скрытому' свойству через некоторое имя свойства как __proto__ где другие не делают (например, Microsofts).

2) Цепочка наследования [obj]-> [конструктор]-> [прототип] вместо [obj]-> [прототип]?

Нет. Смотрите на этот:-

function Base() {}
Base.prototype.doThis = function() { alert("First"); }

function Base2() {}
Base2.prototype.doThis = function() { alert("Second"); }

function Derived() {}
Derived.prototype = new Base()

var x = new Derived()

Derived.prototype = new Base2()

x.doThis();

Это предупреждает "Сначала" не Второй. Если бы цепочка наследования пошла через конструктора, то мы видели бы "Второй". Когда объект создается, текущая ссылка, сохраненная в опытном свойстве Функций, передана объекту скрытая ссылка на ее прототип.

3) 'опытное' свойство нашего объекта (Fido), когда-нибудь проверенная? раз так..., почему 'deathBite' неопределенный (в последней части)?

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

12
ответ дан 30 November 2019 в 21:20
поделиться

Вы не можете изменить прототип объекта, после того как с ним инстанцировали new.

В Вашем примере выше, строки как

fido.prototype = new KillerDog();

просто создает новый названный атрибут prototype на объекте fido, и наборы, которые приписывают новому KillerDog объект. Это не отличается, чем

fido.foo = new KillerDog();

Поскольку Ваш код стоит...

// Doesn't work because objects can't be changed via their constructors
fido.deathBite();

// Does work, because objects can be changed dynamically, 
// and Javascript won't complain when you use prototype 
//as an object attribute name
fido.prototype.deathBite();

Специальное предложение prototype поведение применяется только к конструкторам в JavaScript, где конструкторы functions, с которым назовут new.

7
ответ дан 30 November 2019 в 21:20
поделиться

Ответ числами к Вашим вопросам:

  1. Опытное свойство объекта не называют prototype. Стандартное использование [[prototype]] определять его. Firefox обнародовал это свойство под именем __ первичный __.
  2. Цепочка наследования [obj][prototype object]. Ваше исходное предположение ([obj][constructor][prototype]) является неправильным, и можно легко опровергнуть его путем изменения constructor и/или constructor.prototype, и проверка, к каким методам можно обратиться Ваш [obj] — Вы обнаружите, что эти модификации ничего не изменяют.
  3. prototype свойство на объектах не проверяется и не используется. Можно установить его на то, что Вы любите. JavaScript использует его на функциональных объектах только во время объектной конструкции.

Для демонстрации № 3 вот, код от Dojo:

dojo.delegate = dojo._delegate = (function(){
  // boodman/crockford delegation w/ cornford optimization
  function TMP(){}
  return function(obj, props){
    TMP.prototype = obj;
    var tmp = new TMP();
    if(props){
      dojo._mixin(tmp, props);
    }
    return tmp; // Object
  }
})();

Поскольку Вы видите, что это использует в своих интересах факт это prototype используется только в одном месте путем многократного использования той же функции TMP для всех делегированных объектов с различными прототипами.Действительно? prototype присвоен непосредственно прежде, чем вызвать функцию с new, и это будет изменено, после этого не влияя ни на какие созданные объекты.

Можно найти, что объект создал последовательность в моем ответе на Отношение между [[Прототипом]] и прототипом в JavaScript.

4
ответ дан 30 November 2019 в 21:20
поделиться

Я знаю, что на него уже ответили, но есть способ лучше наследовать. Вызывать конструктор только с целью наследования нежелательно. Один из нежелательных эффектов - это.

function Base() {this.a = "A"}
function Child() {this.b = "B"};

Child.prototype = new Base();

Теперь вы добавили свойство «а» к прототипу Child, которое вы не намеревались делать.

Вот правильный путь (я не изобретал это, Ext-JS и другие библиотеки используют это)

// This is used to avoid calling a base class's constructor just to setup inheritance.
function SurrogateCtor() {}

/**
 * Sets a contructor to inherit from another constructor
 */
function extend(BaseCtor, DerivedCtor) {
  // Copy the prototype to the surrogate constructor
  SurrogateCtor.prototype = BaseCtor.prototype;
  // this sets up the inheritance chain
  DerivedCtor.prototype = new SurrogateCtor();
  // Fix the constructor property, otherwise it would point to the BaseCtor
  DerivedCtor.prototype.constructor = DerivedCtor;
  // Might as well add a property to the constructor to 
  // allow for simpler calling of base class's method
  DerivedCtor.superclass = BaseCtor;
}

function Base() {
  this.a = "A";
}

Base.prototype.getA = function() {return this.a}

function Derived() {
  Derived.superclass.call(this);  // No need to reference the base class by name
  this.b = "B";
}

extend(Base, Derived);
// Have to set methods on the prototype after the call to extend
// otherwise the prototype is overridden;
Derived.prototype.getB = function(){return this.b};
var obj = new Derived();

Еще более простой способ - добавить третий параметр для расширения там, где вы указываете метод производного класса, чтобы вам не нужно вызывать extension, а затем добавлять методы к прототипу

extend(BaseCtor, DerivedCtor, {
  getB: function() {return this.b}
});

. Есть еще много других вещей, которые вы можете сделать для синтаксического сахара.

Об этом писал в блоге: http://js-bits.blogspot.com/2010/08/javascript-inheritance-done-right.html

2
ответ дан 30 November 2019 в 21:20
поделиться
Другие вопросы по тегам:

Похожие вопросы: