Работая над библиотекой Paper.js
, я обнаружил в базе кода способ создания экземпляра класса, который раньше никогда не использовал. Например, здесь используется для создания экземпляра класса Shape
.
Этот образец реализации может быть упрощен до следующего: дан класс Ball
и метод createBall()
, который его создает:
function Ball() {}
function createBall() {return new Ball()}
Конечно, мы можем получить экземпляр шара, позвонив по номеру:
var ball = createBall();
Но что более удивительно, мы также можем получить экземпляр ball, вызвав (обратите внимание на ключевое слово new
):
var ball = new createBall();
Или как более абстрактный способ:
var ball = new function() {return new Ball()};
Поскольку createBall()
возвращает экземпляр Ball
, создается впечатление, что мы создаем экземпляр класса Ball
, используя ключевое слово new
для его экземпляра.
Но, как видно из следующего кода, это не разрешено и выдает ошибку, если мы делаем это вручную:
var ball1 = new Ball();
var ball2 = new ball1();
// error: ball1 is not a constructor
Может кто-нибудь объяснить мне, что за этим стоит?
Вот сравнительный пример различных методов создания экземпляров:
// Class
function Ball() {}
// Method creating an instance of the class
function createBall() {
// Instantiate the class
var ball = new Ball();
// Return the instance
return ball;
}
// Expected: instantiating directly works
var ball1 = new Ball();
console.log('ball1', ball1 instanceof Ball); // outputs true
// Expected: instantiating through the creation method works
var ball2 = createBall();
console.log('ball2', ball2 instanceof Ball); // outputs true
// Unexpected: instantiating like this surprisingly works
var ball3 = new createBall();
console.log('ball3', ball3 instanceof Ball); // outputs true
// Expected: instantiating like this throws an error
var ball4 = new ball1();
// error: ball1 is not a constructor
Редактировать
Прочитав комментарий @ robert-zigmond, я обнаружил еще один вводящий в заблуждение случай:
function Dog() {}
function Ball() {
return new Dog();
}
var instance = new Ball();
console.log('is instance a Ball ?', instance instanceof Ball); // false
console.log('is instance a Dog ?', instance instanceof Dog); // true