2009-12-18 1 views
0
var foo = (function() { 
    var proxy = {}, 
     warning = false; 

    proxy.warn = function(msg) { 
     if (!warning) { 
      warning = true; 
      alert(msg); 
     } 
     return this; //For the purpose of method chaining we return proxy object. 
    } 

    function func() { 
     alert(warning); //This is a private function relative to foo. 
    } 

    return proxy; 
}()); 

foo.warn(); //will alert 
foo.warn(); //will not alert since warning has been set to true 

Я запутался в создании экземпляра здесь, так как не используется новое ключевое слово, которое удерживает значение предупреждения? Существует ли какая-либо утечка здесь с точки зрения срока действия предупреждения.Изучение области видимости и объекта объекта JavaScript

Спасибо.

ответ

1

И proxy.method, и func имеют доступ к a через closureproperty.Для получения более подробной информации о масштабах и объектов, проверить эту статью, которая всплыла в последнее время: A Concise, Executable Guide to JavaScript Objects, Variables, Functions, and Prototypes

код, который Вы отправили подходит то, что известно как «module pattern» и становится очень популярным способом для определения объектов в JavaScript, как он упрощает создание частных переменных и методов (воспользовавшись свойством закрытия, как упоминалось ранее).

1

Этот ответ на другой вопрос, действительно помогло мне расширить мое понимание того, как работает JavaScript объекты:

JavaScript function aliasing doesn't seem to work

Как для вашего фрагмента кода, давайте разбить его. Начните с изучения структуры высокого уровня: var foo = (exrpession);. Вы могли бы так же легко сказать: var foo = expression;, но IIRC - круглые скобки, необходимые для обработки специфической особенности IE.

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

function() { 
    alert('test'); 
    return 42; 
}(); 

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

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

+0

@Joel: Я обновил код, чтобы показать, почему такая приватная переменная необходима в моем случае. Благодарю. – Jeff

2

Колодец a жить в верхней функции закрытия function() {....

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

proxy.getValueOfA=function(){return a} 

, то вы можете позвонить foo.getValueOfA()

Как замечание:

var proxy={} 

является короткая форма от var proxy=new Object(), так что есть instanciation.

+0

В коде 'var proxy = {}' используется так называемая компактная запись объекта. Это ярлык и не требует «нового» для создания объекта. –

+0

Как говорит Джоэл Кохорн, {} эквивалентен новому объекту(), поскольку [] эквивалентен новому массиву() – Patrick

1

этого

return proxy; 
}()); 

должен быть этот

return proxy; 
})(); 

и это

function() { 
    alert('test'); 
    return 42; 
}(); 

не работает ... синтаксическую ошибку. вы должны попробовать свой код, прежде чем надеть его здесь. уверен, что вы имели в виду это:

(function() { 
    alert('test'); 
    return 42; 
})(); 

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

var foo = (function() { 
    var proxy = {}, // private 
    proxy.warn = function(msg) { 
    ... 
    return proxy; // publicly accessible 

это то же самое, что

var foo = { warn: function(){ /* code */ } }; 
+0

@Dan: почему вы говорите «побеждает всю точку закрытия области», я хочу провести закрытый переключатель так, это предупреждение должно быть уволено или нет. – Jeff

+0

Да, вы правы, это сделало бы это. возможно, я не смотрел на то, что вы пытались сделать, только как вы это делали. в любом случае, var внутри анонимной функции будет закрыт, поэтому доступ к нему может быть доступен только общественным или защищенным членам. Я привык возвращать своих публичных участников в заявлении о возврате (таким образом вы визуально/логически отделяете своих частных/защищенных членов. window.foo = (function() { var warning = true; return ({warn : function (msg) {return (warning? alert (msg): this);}}); })(); –

Смежные вопросы