Как получить значение свойства в литеральном объекте в автоисполняемом методе - PullRequest
2 голосов
/ 18 марта 2012

Я хочу сделать это:

var person = {
    name: "John",
    __test__: (function() {alert(this.name)})()
}

но this.name не определено. Как узнать его значение тогда?

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

var person = {
    name: "",
    __test__: (function() {name = "john"})()
}`

«Джон» может появиться в реальном мире из объекта-макета, базы данных, что угодно, я хочу сказать, что я хочу сделать это САМОСТОЯТЕЛЬНЫМ способом, а не вызывать test из внешнего объекта.

Ответы [ 4 ]

4 голосов
/ 18 марта 2012

Вы не можете сделать это, используя литерал объекта.this относится к person после литерал оценивается, во время оценки this относится к родительской области.Вы можете обернуть конструкцию объекта в функцию, чтобы быть уверенным, что this ссылается на текущую область (т. Е. Область функции).Что-то вроде:

var person = function(){
    this.name = 'John';
    this.__test__ = (function(){alert(this.name);}());
    return this;
}();

Или используя переменные внутри области действия функции:

var person = function(){
    var _name = 'John'
        ,_test = (function(){alert(_name);}());
    return { name: _name, __test__: _test };
}();

Или обернуть вещи в более общую фабричную функцию:

function objFactory(obj){
    var nwObj = {};
    for (var l in obj){
        if (obj.hasOwnProperty(l)){
            if (obj[l] instanceof Function && /^auto_/i.test(l)){
             nwObj[l.replace(/^auto_/i,'')] = obj[l].call(nwObj);
            }
            else {
             nwObj[l] = obj[l];
            }
        }
    }
   return nwObj;
}
//=> usage
var person = objFactory(
               { name: '', 
                 auto_name: function(){
                             this.name='John'; 
                             return this.name;
                            }
                }
             );
 alert(person.name); //=> John

И, наконец,(не все с этим согласятся) вы можете создать обработчик загрузки в Object.prototype:

Object.prototype.load = function(){
    for (var l in this){
        if (this.hasOwnProperty(l) 
            && this[l] instanceof Function 
            && /^auto_/i.test(l)) {
          this[l].call(this);
          delete this[l];
        }
    }
    return this;
}
//=> usage
var person = {
               name: '', 
               auto_name: function(){this.name='John';}
             }.load();
alert(person.name); //=> John
1 голос
/ 18 марта 2012

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

var func = function() {return this;}; 
// when invoked as such
func();
// will return global namespace (or window in a browser).

var obj = {"func": func};

obj.func(); 
// now calling func on obj so this is now obj and returns obj

Может быть, вы могли бы получить то, что вы хотите с помощью конструктора:

function MyObject() {

    this.name = "John";
    this.__test_func__ = function() {alert(this.name);};
    this.__test__ = this.__test_func__();

    // or you could try passing in your object explicitly
    this.__test__ = (function(pseudo_this){alert(pseudo_this.name);})(this);
}

var obj = new MyObject();

Еще одна вещь, оповещение не имеет возвращаемого значения (оно возвращает неопределенное значение). Я полагаю, вы знали об этом и просто пытались проверить состояние объекта на полпути во время строительства. Вам нужно будет использовать конструктор, а не литерал, если вы хотите сделать что-то более сложное, чем просто указание содержимого объекта.

1 голос
/ 18 марта 2012

Сделайте следующее:

var person = {
    name: "John",
    __test__: function() { alert(this.name) }
};
person.test();

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

Что и почемуон предупреждает undefined, Google знает, как работают JavaScript-закрытия и анонимные функции. По сути, this теряет свой контекст при самозапуске анонимных функций.

1 голос
/ 18 марта 2012

Область кода с автоисполняемой функцией - это window (я полагаю, это потому, что именно он вызвал функцию, а не person).

Итак,Я думаю, что это не может быть сделано (таким образом).

увидеть это DEMO

Почему бы не использовать это вместо:

var person = {
    name: "John",
    __test__: function() {alert(this.name)}
}
person.__test__();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...