Является ли использование нового в Javascript таким же, как не использовать его? - PullRequest
6 голосов
/ 23 декабря 2011

Рассмотрим этот код:

function klass( z ) {
    this.a = z;
    return this;
}

var b = klass( 5 );
var c = new klass( 9 );

Когда я запускаю его в Chrome и проверяю в консоли, b оказывается типа DOMWindow, а c типа klass.

Хотя оба имеют свойство a, фактически оба являются экземпляром из класса .

  • Используете или не используете новое, то же самое?
  • То же самое в этом примере, но отличается в других ситуациях?
  • Есть ли различия в эффективности или поведении?

Ответы [ 3 ]

6 голосов
/ 23 декабря 2011

Без new ваша функция будет работать только с тем, с чем this был связан, в вашем случае с DOMWindow.Новый экземпляр не создается, свойство a устанавливается для объекта окна.Вызов метода дважды обнуляет предыдущий результат.

Попробуйте это:

var b = klass(5)
log.info(b.a)
log.info(b == window)  // b is actually the window object
log.info(window.a)   // also 5

var c = klass(6)
log.info(b.a)     // now set to 6
log.info(c == b)  // c and b are the same
6 голосов
/ 23 декабря 2011

Когда функция вызывается следующим образом

klass(6);  //called function invocation

this будет установлен как глобальный объект, или, если вы находитесь в строгом режиме, undefined

В результате первый пример (без new) вернет глобальный объект с новым свойством a. В строгом режиме он выдаст ошибку, поскольку this будет установлен на undefined, и вы не можете добавить свойство a к undefined.

Когда вы вызываете функцию с new

new klass( 9 );  //called constructor invocation

значение this устанавливается для нового объекта и неявно возвращается из функции - нет необходимости говорить return this

Для полноты, когда вы вызываете функцию как метод объекта:

foo.method();  //called method invocation

this будет установлено для объекта - foo в этом случае.

И когда вы вызываете функцию с apply (или вызовом)

method.apply(foo)  //called apply invocation 

this устанавливается на то, что вы укажете - foo снова

EDIT

Я упомянул strict mode в своем ответе. Страница использует строгий режим, если она имеет

"use strict"

в самом верху.

3 голосов
/ 23 декабря 2011

Это абсолютно не то же самое:

var a = klass(42);
console.log(a.a); // 42
var b = klass(69);
console.log(b.a); // 69
console.log(a.a); // 69

Если вы не позвоните new, вы не получите ничего нового.

...