Один из способов - использовать JOptionPane.showInputDialog . Приложение «останавливается» с помощью модального диалога, и вы очень легко получаете его ввод.
Пример:
//returns null if user closes the dialog.
String answer = JOptionPane.showInputDialog("What is your first name?");
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
не имеет никакого особого значения, как указано ранее объект не поддерживает ссылку на свой прототип через такое имя свойства.
Вы не можете изменить прототип объекта, после того как с ним инстанцировали 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, где конструкторы function
s, с которым назовут new
.
Ответ числами к Вашим вопросам:
prototype
. Стандартное использование [[prototype]]
определять его. Firefox обнародовал это свойство под именем __ первичный __.[obj]
⇒ [prototype object]
. Ваше исходное предположение ([obj]
⇒ [constructor]
⇒ [prototype]
) является неправильным, и можно легко опровергнуть его путем изменения constructor
и/или constructor.prototype
, и проверка, к каким методам можно обратиться Ваш [obj]
— Вы обнаружите, что эти модификации ничего не изменяют.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.
Я знаю, что на него уже ответили, но есть способ лучше наследовать. Вызывать конструктор только с целью наследования нежелательно. Один из нежелательных эффектов - это.
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