Создание новых объектов в JavaScript - PullRequest
1 голос
/ 20 декабря 2011

Возможно, мне не хватает чего-то действительно базового в знании 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 ]

2 голосов
/ 20 декабря 2011

Ваш первый пример был литералом объекта:

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 и недоступенкак собственность на экземпляры лица;однако функция showPrivateData и любые другие привилегированные функции, которые вы могли бы добавить, образовали бы замыкание над ней и имели бы к ней доступ.

Наконец, обратите внимание, что функции конструктора могут принимать параметры:

function Person(name, age) {
    this.name= name;
    this.age= age;
};
1 голос
/ 20 декабря 2011

Вы отвечаете на свой вопрос. Конструктор (то, что идет рядом с new) должен быть функцией в JavaScript.

1 голос
/ 20 декабря 2011

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.

и вы в основном делаете оба шага во втором случае.

0 голосов
/ 20 декабря 2011

Первая версия использует литерал объекта для создания единственного экземпляра объекта, который назначен person. Его нельзя использовать как конструктор с new для создания других объектов из person.

Во второй версии используется функция, которую можно вызвать как конструктор для создания новых объектов с new person().

Именно так new работает в JavaScript. По сути, если вы хотите иметь возможность создавать несколько экземпляров из шаблона (аналогично тому, как классы работают на других языках), используйте синтаксис new FunctionName(). Если вам нужно создать только один экземпляр определенного объекта, вы можете использовать первый синтаксис.

Обратите внимание, что в первой версии вы можете сказать:

person.set('Victor',12);
alert(person.name); // 'Victor'

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

...