Подтвердить что ты не робот

Javascript: Ссылка на объект Literal в собственной ключевой функции вместо 'this'

Является ли проблематичным ссылаться на литерал объекта внутри функции, которая является частью этого самого литерала? Кажется, что все работает отлично, но я хочу убедиться, что нет других последствий.

Вот пример того, что я говорю:

вместо:

var obj = {
    key1: "it",
    key2: function(){return this.key1 + " works!"}
};
alert(obj.key2());

с помощью:

var obj = {
    key1: "it",
    key2: function(){return obj.key1 + " works!"}
};
alert(obj.key2());
4b9b3361

Ответ 1

Оба могут быть проблематичными.

var obj = {
    key1: "it",
    key2: function(){ return this.key1 + " works!" }
};
var func = obj.key2;
alert(func()); // error

Когда func не вызывается как метод obj, this может ссылаться на что-то еще (здесь: глобальный объект "window" ).

var obj = {
    key1: "it",
    key2: function(){ return obj.key1 + " works!" }
};
var newref = obj;
obj = { key1: "something else"; };
alert(newref.key2()); // "something else works"

Здесь мы обращаемся к объекту из другой ссылки, хотя obj в функции теперь может указывать на какой-то другой объект.

Итак, вам нужно будет выбрать, какой случай более вероятен. Если вы действительно хотите сделать это безопасным, вы можете использовать закрытие, где obj имеет область действия и не может быть изменено:

var obj = (function(){
    var local = {
        key1: "it",
        key2: function(){ return local.key1 + " works always!" }
    };
    return local;
})();

или вы bind() функция для объекта:

var obj = {
    key1: "it",
    key2: function(){ return this.key1 + " works always!" }
}
obj.key2 = obj.key2.bind(obj);

Ответ 2

Будет разница в привязке области видимости переменной. Если вы измените obj позже, вы измените возвращаемое значение key2:

var newobj = obj;
obj = { key1: "new" };
alert(newobj.key2());

Теперь он предупреждает "новые работы!", потому что, хотя вы вызываете key2() в исходном объекте (который теперь newobj), ссылка на obj.key1 теперь привязывается к значению нового obj экземпляр. Использование this предотвращает это.

Демо: http://jsfiddle.net/m6CU3/

Ответ 3

Если вы не используете объект прототипа, вы czn пойдете так. поскольку все экземпляры вашего объекта возвращают значение экземпляра obj...

Ответ 4

В зависимости от ситуации может применяться любой из этих методов или оба эти метода.

Значение this внутри функции зависит от того, как была вызвана функция. Если вы вызываете функцию как свойство объекта следующим образом:

obj.key2();
//or
obj["key2"]();

Тогда this будет этот объект. Независимо от того, был ли объект создан посредством литерала объекта или каким-либо другим способом, не имеет значения.

Но вы можете использовать .call() или .apply() для вызова функции и явно установить this на какой-либо другой объект.

Рассмотрим также:

var obj = {
    key1: "it",
    key2: function(){return this.key1 + " works!"}
};
alert(obj.key2()); // alerts "it works!"

var func = obj.key2;
alert(func())​;     // alerts "undefined works!"

Я настраиваю func для ссылки на ту же функцию, что и obj.key2, но вызов ее как func() не устанавливает this в obj.

Для получения дополнительной информации см. то, что MDN должно сказать о this.

Ответ 5

Я не думаю, что какие-то последствия с моей головы. Просто убедитесь, что вы случайно не сделали это в любой момент:

var obj = {
    key1: "it",
    key2: key1 + " works!"
}

Как это приведет к ошибке. Помимо этого, вы должны быть добрыми!