Я видел много таких вещей, и я ищу подходящее решение для основного наследования JavaScript:
function Food(){} // Food constructor (class)
function Bread(){} // Bread constructor (class)
var basicFood = new Food(); // Food classes will inherit from this basicFood instance.
Bread.prototype = basicFood; // Bread now inherits from Food.
var bread = new Bread(); // We create some bread!
bread.constructor == Food; // Though, now we feel very uneasy about how
// the constructor is wrong,
Bread.prototype.constructor = Bread; // So we explicitly set the prototype constructor
bread = new Bread(); // and when we create our new bread,
bread.constructor == Bread; // we feel much better as the constructor appears correct.
// The issue? Suppose we have another food item,
// like in a real inheritance situation:
function Sushi(){}; // We might be
Sushi.prototype = basicFood; // tempted to do
Sushi.prototype.constructor = Sushi; // the same thing
var sushi = new Sushi(); // again
sushi.constructor == Sushi; // Before we realize
bread.constructor == Sushi; // that we've ruined our bread.
basicFood.constructor != Food; // More importantly, we've really ruined all our basicFood,
// because while it a prototype,
// it also an object in its own right,
// and deserves an accurate constructor property.
Кто constructor
должен быть действительно?
И что constructor
имеет какое-либо отношение к результатам instanceof
?
Мне интересно, что правильно? Я понимаю, что многие предпочли бы дать каждому классу продуктов (хлеб, суши и т.д.) Новый экземпляр Food, а не дать им все тот же пример basicFood. Я хочу это более оптимальное решение (не делая ненужные экземпляры).
Учитывая нашу пищу, хлеб, суши и basicFood:
function Food(){}
function Bread(){}
function Sushi(){}
var basicFood = new Food();
Я подумал, что могу создать вспомогательный помощник,, который определял бы неперечислимый непереписываемый конструктор свойств без конфигурации для нового экземпляра:
Bread.prototype = basicFood; // We still simply inherit from basicFood
Sushi.prototype = basicFood;
// But we use this helper function when we make instances
function reconstructify(target, Constructor){
return Object.defineProperty(target, 'constructor', {
enumerable: false,
configurable: false,
writable: false,
value: Constructor
});
}
var bread = reconstructify(new Bread(), Bread); // Like so
var sushi = reconstructify(new Sushi(), Sushi);
При тестировании этого я понял, что instanceof
не ведет себя так, как я думал, это может:
// True expressions for testing -- all good
basicFood.constructor == Food;
bread.constructor == Bread;
sushi.constructor == Sushi;
basicFood instanceof Food; // good also
bread instanceof Food;
sushi instanceof Food;
sushi instanceof Bread; // uh oh, not so good that this is true
bread instanceof Sushi; // why is this?
Внимательно изучая его, я не могу заставить instanceof
работать так, как я предполагал:
function Food(){}
function Bread(){}
function Sushi(){}
var basicFood = new Food();
Bread.prototype = basicFood;
Sushi.prototype = basicFood;
var bread = new Bread();
var sushi = new Sushi();
sushi instanceof Bread; // why true?
bread instanceof Sushi; // why true?
Я хочу, чтобы bread
и sushi
оба были экземплярами Food - не друг другу.
Как я могу достичь наследования JavaScript, сохраняя ожидаемое поведение для свойства constructor
, а также оператора instanceof
?