2013-03-21 2 views
0

В Javascript следует использовать способ создания классов (или объектов);Javascript Разница между нормальной функцией и функциональным объектом

function MyObj() 
{ 
    this.someVar = "xyz"; 
    this.someMethod = function(){} 
} 

Простой вопрос: насколько отличается эта функция от нормальной функции JavaScript ... скажем, функция, которая добавляет 2 числа?

+0

Этот вопрос отчасти расплывчаты. Что ты конкретно имеешь ввиду? В этой функции вы назначаете значение переменной и вызываете другую функцию вне вашей текущей функции. Если вы добавите два номера, вы, вероятно, останетесь внутри функции и не будете вызывать другую функцию. Но я не думаю, что это ваш вопрос ..? – Joetjah

+0

II рекомендовал бы прочитать статью [Именованные функциональные выражения, демистифицированные] (http://kangax.github.com/nfe/) – C5H8NNaO4

+0

Вы имеете в виду разницу между встроенными функциями и определенными пользователем функциями в javascript? –

ответ

3

Функция не отличается. В чем разница, как вы их называете.

Например, те, имеют один и тот же эффект:

function MyObj(){ 
    this.someVar = "xyz"; 
    this.someMethod = function(){ 
     console.log(this.someVar); 
    } 
} 
var obj = new MyObj(); 
obj.someMethod(); 

и

function someMethod(){ 
    console.log(this.someVar); 
} 
function MyObj(){ 
    this.someVar = "xyz"; 
} 
var obj = new MyObj(); 
someMethod.call(obj); 

и

function someMethod(){ 
    console.log(this.someVar); 
} 
function MyObj(){ 
    this.someVar = "xyz"; 
} 
var obj = new MyObj(); 
obj.f = someMethod; 
obj.f(); 

Как помечено ваш вопрос , я закончить, говоря, лучший способ построить вашу функцию был бы следующим:

function MyObj(){ 
    this.someVar = "xyz"; 
} 
MyObj.prototype.someMethod = function(){ 
    console.log(this.someVar); 
} 
var obj = new MyObj(); 
obj.someMethod(); 

Таким образом, все экземпляры MyObj разделяют ту же функцию и, следовательно, легче.

+0

они не _quite_ то же самое - в первой версии 'someMethod' будет иметь доступ к любым другим лексическим областям переменных, которые объявлены внутри' MyObj'. В других версиях метод не разделяет лексическую область, поэтому не мог получить к ним доступ. – Alnitak

+0

@ Алнитак Правильно, но только если есть переменные с областью. –

1

Разница заключается не столько в содержании функции, сколько в ее названии.

Если вы позвоните по номеру var myObj = new MyObj(), тогда будет создан новый объект. По условным функциям, предназначенным для использования, начинаются с заглавной буквы.

Если вы должны были вызвать функцию без ключевого слова new, то точно такие же вещи происходят внутри функции, за исключением того, что this будет глобальным объектом вместо вновь созданного объекта. Это не имеет значения в простой функции «добавить 2 числа», но может вызвать очень странные ошибки, если вы забудете об этом.

Один из способов убедиться, что это не имеет значения, если вы забыли new вызов не поставить это в верхней части вашей функции:

function MyObj() { 
    if (! (this instanceof MyObj)) { 
     return new MyObj(); 
    } 
    ... 
} 
+0

Итак, ваша функция выше, убедитесь, что 'this' ссылается на' MyObj() ', но не глобальный контекст. правильно? –

+0

@Mr_Green yes - если используется 'new', то' this' уже является 'MyObj', поэтому конструктор продолжается как обычно. В противном случае функция возвращает результат явного вызова 'new' на себя. – Alnitak

+0

Ahh yes nice one :). Извините, я не понимаю этого раньше. –

1

Нет. Важно использовать ключевое слово new.

Смотрите здесь:

function Fun(){ 
    this.method = function(){ 
     return "Bar"; 
    } 
    return "Foo"; 
} 

var value = Fun(); // assigns the return value of Fun() to value 
alert(value); // "Foo" 
// alert(value.method()); // won't work because "Foo".method doesn't exist 

var instance = new Fun(); // assigns a new instance of Fun() to instance 
alert(instance); // [object Object] 
alert(instance.method()); // "Bar" 
+0

nb: в первом примере вы на самом деле создали 'window.method' _instead of_' value.method'. – Alnitak

+0

это озадачивает - обычно, если вы «возвращаете» какое-то другое значение из конструктора, то оно заменяет «это», но этого здесь не происходит. Возможно, это правило работает, только если вы возвращаете объект вместо примитива? – Alnitak

+0

RE: 'window.method' создается в первом примере - это правильно и замечательно. RE: объект возврата, заменяющий это - это тоже правильно. И это способ создания singleton в JavaScript: http://jsfiddle.net/5pFqd/ –

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