Изменяемый параметр Javascript? - PullRequest
0 голосов
/ 27 января 2012

Это всего лишь технический вопрос о javascript. В javascript один из членов моей группы обнаружил что-то странное в создании объектов javascript. По какой-то причине параметры в объекте уже обрабатываются как члены, не назначая их никаким переменным-членам, созданным в конструкторе объекта. Параметры также могут изменяться, как показано в блоке кода ниже.

Вот код, который показывает тестирование, которое мы проводим.

function NamedItem(name)
{
    name = 5;

    this.getName = function ()
    {
        return name;
    }
}


document.write(namedItem.getName() + "\n");  //5

Это законно? Это опасно?

Ответы [ 2 ]

4 голосов
/ 27 января 2012

Это называется замыканием .
Вложенные функции могут обращаться к переменным из своей родительской функции и продлевать время жизни переменных за пределы выполнения родительской функции.1007 * Это не имеет ничего общего с объектами.

1 голос
/ 27 января 2012

Просто чтобы прояснить, есть некоторые потенциально глупые вещи о том, что вы делаете. Позвольте мне объяснить несколько принципов.

  1. Если вы объявляете переменную или переменные в качестве аргументов функции, такой как function(arg1, arg2), то с точки зрения самих переменных (а не их значений) это, по сути, то же самое, что сказано в верхней части вашей функции var arg1; var arg2;. Объявлены для вас автоматически. Даже если вы попытаетесь переопределить их, они все равно будут работать с переданными аргументами!

  2. Функции являются объектами. Объекты могут иметь свойства. Поэтому функции могут иметь свойства, такие как this.getName = function().

  3. Как указал @SLaks, вы создаете замыкание в своей версии метода getName. Закрытие фиксирует положение вещей над ним, когда оно создается. Поэтому, если в его области видимости есть переменная name, она будет иметь доступ к этой переменной имени в своей области видимости. Это очень нормальная практика в JavaScript, и вам удалось создать частное свойство (name) с функцией открытого доступа (getName). Молодцы.

  4. Я предполагаю, что вы используете экземпляры NamedItem с таким ключевым словом new, как это. var item = new NamedItem("javascripter"). Другой способ (и тот, который использует меньше памяти, чем то, что вы делаете, - это добавление функции getName() к прототипу для NamedItem, как я покажу ниже. Недостатком подхода к прототипу является то, что вы могли бы так же легко получить доступ к _name непосредственно. В JavaScript нет частных свойств в традиционном смысле, но некоторые люди используют префикс подчеркивания, чтобы указать людям, что они являются частными, а не использовать их. Этот подход (прототипы) использует меньше памяти, чем ваш подход, потому что если вы создаете несколько экземпляров NamedItem, все они совместно используют один прототип.

Использование прототипов вместо:

function NamedItem(name) {
    this._name = name
}

NamedItem.prototype.getName = function() {
    return this._name
}

Надеюсь, у вас есть о чем подумать!

J

...