Создание новых объектов в JavaScript
Я, вероятно, упускаю что-то действительно базовое в знании JavaScript, но почему это не работает?
var person = {
name:"",
age:0,
set : function(name,age){
this.name = name;
this.age = age;
}
}
var me = new person; // ERROR: Object doesn't support this action!
me.set('Victor',12);
me.name //Victor
Но это делает:
var person = function(){
this.name="";
this.age=0;
this.set = function(name,age){
this.name=name;
this.age=age;
}
}
var me = new person(); //WORKS!
me.set('Victor',12);
me.name; //Victor
4 ответа
Ваш первый пример был литералом объекта:
var person = {
name: "Bob",
//etc
};
Вы создали один объект с именем person, и это все. Концепция создания новых людей не имеет смысла.
Если вы хотите создать что-то, что можно использовать для создания большего количества объектов по желанию, вы должны использовать функцию, как ваш второй пример.
Обратите внимание, что функции, предназначенные для использования в качестве конструктора, начинаются с заглавной буквы по соглашению. Также обратите внимание, что когда вы устанавливаете функцию внутри вашего конструктора, используя
this.functionName = function() .....
это создает привилегированную функцию, так как она имеет доступ как к открытым, так и к закрытым членам. Если этой функции набора нужен только доступ к публичным свойствам, она обычно добавляется к функции prototype
, Вот как все это может выглядеть
function Person() {
this.name = "";
this.age = 0;
};
Person.prototype.set = function(name,age) {
this.name = name;
this.age = age;
}
А вот как может выглядеть привилегированный метод
function Person() {
var localData = "Hello";
this.showPrivateData = function() {
alert(localData);
};
this.name="";
this.age=0;
};
localData
является локальным для Person
функция, и не может быть доступна как свойство в экземплярах Person; Тем не менее showPrivateData
Функция и любые другие привилегированные функции, которые вы можете добавить, сформируют замыкание над ним и будут иметь к нему доступ.
Наконец, обратите внимание, что функции конструктора могут принимать параметры:
function Person(name, age) {
this.name= name;
this.age= age;
};
В JavaScript нет классов (хотя вы можете имитировать их), вот почему. А также new
работает только на функции (в этом случае создает специальную переменную this
внутри функции, которая возвращается неявно после вызова функции).
Итак, при использовании этого:
var person = {
name:"",
age:0,
set : function(name,age){
this.name = name;
this.age = age;
}
};
Вы уже создали объект (который имеет функцию в качестве одного из своих свойств).
Но когда вы используете это:
var person = function(){
this.name="";
this.age=0;
this.set = function(name,age){
this.name=name;
this.age=age;
}
};
вы только создаете функцию, которая возвращает this
со всеми назначенными свойствами, когда функция вызывается с new
,
Какая документация говорит
Как документация new
Оператор Mozilla Developer Network сообщает:
new
Оператор создает экземпляр пользовательского типа объекта или одного из встроенных типов объектов, который имеет функцию конструктора....
Создание пользовательского объекта требует двух шагов:
- Определите тип объекта, написав функцию.
- Создайте экземпляр объекта с
new
,
и вы в основном делаете оба шага во втором случае.
Вы отвечаете на свой вопрос. Конструктор (вещь, которая идет рядом с new
) должна быть функцией в JavaScript.
Первая версия использует литерал объекта для создания одного экземпляра объекта, который назначен person
, Это не может быть использовано как конструктор с new
создавать другие объекты из person
,
Вторая версия использует функцию, которую можно вызывать в качестве конструктора для создания новых объектов с new person()
,
Это просто способ new
работает в JavaScript. По сути, если вы хотите иметь возможность создавать несколько экземпляров из шаблона (аналогично тому, как классы работают на других языках), используйте new FunctionName()
синтаксис. Если вам нужно создать только один экземпляр определенного объекта, вы можете использовать первый синтаксис.
Обратите внимание, что в первой версии вы можете сказать:
person.set('Victor',12);
alert(person.name); // 'Victor'
Также обратите внимание, что если вы создаете функцию, предназначенную для использования в качестве конструктора, соглашение заключается в использовании заглавных букв для первой буквы ее имени (или первой буквы каждого слова в имени).