2015-11-26 4 views
0

С помощью этого кода (jsfiddle):Почему новый экземпляр создается без нового оператора?

Animal = function() { 
}; 

Animal.prototype.bark = function() {}; 

Animal.inspect = function() { 
    console.log(this.prototype.hasOwnProperty('bark')); // true 
} 

Animal.inspect(); 

this в inspect, кажется, новый экземпляр животных (а не глобальный или window сферы).

Почему?

ответ

2

Это не является экземпляром Animal, но сам Animal объект (Animal на самом деле не класс)

Переменная this не является эквивалентом экземпляра объекта (например, self во многих других языках). Это «контекст», который может иметь любую ценность. Это значение может быть разрешено многими (запутывающими) способами. Один из них находится в вызове функции, где функция является членом объекта (и функция не вызывалась, указав новый контекст через .call или .apply), и в этом случае он будет разрешен экземпляру объекта. Поскольку Animal является объектом, Animal.inspect квалифицируется как «метод», а в Animal.inspect() контекст this разрешен к Animal.

Вы можете сделать этот небольшой эксперимент:

Animal = function() { 
}; 

Animal.prototype.bark = function() {}; 

Animal.doSomething = function() { 
    this.hello = 'hello'; 
}; 

Animal.doSomething(); 
console.log(Animal.hello); // hello 

И, кстати, в JS вы можете отлично создавать новые объекты без оператора new, так как на самом деле вы сделали при определении Animal.

+0

JS не имеет классов как таковых, но Animal является «классом» настолько, насколько можно написать 'new Animal()' и получить экземпляр того, что имеет свойство 'bark' (но это не будет иметь свойство 'inspect') –

+0

@ChrisLear Я согласен, и я этого не делаю. 'new Animal' не является экземпляром' Animal', это объект, который делегирует на 'Animal'. В любом случае ... давайте не будем подробно обсуждать странности JS :) – bgusach

+0

@bgusach: Конечно, «новый экземпляр Animal Animal» ?! Объект (мы называем его экземпляром) делегирует «Animal.prototype». – Bergi

3

Вы не создаёте экземпляр.

Вы вызываете inspect() на сам объект-конструктор.

Так this является Animal, а затем вы исследуете прототип (не текущий объект), чтобы увидеть, если он имеет заднюю собственность.

2

this в инспектировать, кажется, новый экземпляр Animal

первой из всех функций в JavaScript также являются объектами

так, когда вы делаете следующее

Animal.inspect(); 

this в inspect() установлен на Animal

+0

Ну, не обязательно. – bgusach

+0

@bgusach и почему не – Ramanlfc

+0

"this in invoke()" что "invoke()"? –

Смежные вопросы