2014-02-05 2 views
0

Мой вопрос точно так же, как это один Javascript revealing module pattern, public propertiesJavascript показательны шаблон модуля и переменные

В этом потоке, ответ был дан, но не «почему». . Вот тот же вопрос пересчитаны с моим собственным примером:

myApp.User = function() { 
    var firstName = 'Default', 
     lastName = 'Default'; 

    function setFirstName(name) { 
     firstName = name; 
    } 

    function setLastName(name) { 
     lastName = name; 
    } 

    function getFirstName() { 
     return firstName; 
    } 

    function getLastName() { 
     return lastName; 
    } 

    return { 
     getLastName: getLastName, 
     **getFirstName: getFirstName**, 
     setLastName: setLastName, 
     setFirstName: firstName 
    }; 
}; 

В этом случае пользователь() getFirstName всегда Evals «По умолчанию» - даже если я изменить его на другое значение с помощью функции setFirstName.

Если я заменить setFirstName как:

return { 
    getLastName: getLastName, 
    **getFirstName: getFirstName**, 
    setLastName: setLastName, 
    setFirstName: firstName 
}; 

Я могу получить доступ к измененному значению. Я понимаю, что var firstName передается по значению, поэтому обновленные значения не отражаются. Я не понимаю, что особенного в этой функции. Где указатель на значение внутри функции? Почему все функции «магически» получают доступ к обновлению (-ам)?

+2

Если он «всегда Evals на„по умолчанию“», то вы не называя 'setFirstName' первым на * тот же объект *. Кроме того, '{setFirstName: firstName}' подразумевает, что 'obj.setFirstName' * не является * функцией (поскольку' firstName' * не является * функцией), поэтому вы не можете называть его, даже если хотите. (И поскольку код * не меняет * переменную firstName .. конечно, он всегда будет «Default».) – user2864740

+1

Возможный дубликат [Как работают блокировки JavaScript?] (Http://stackoverflow.com/questions/111102/how-do-javascript-closures-work) – Philipp

+0

Должно ли последнее свойство возвращаемого объекта быть 'setFirstName: setFirstName', а не' setFirstName: firstname'? –

ответ

0

Где указатель на значение внутри функции?

В объем функции - которая содержит все переменные, он имеет доступ. Этот доступ делает функцию closure фактически.

Почему все функции «магически» получают доступ к обновлению (-ам)?

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

+0

, отмечая это как правильное, потому что оно лежит в основе моего вопроса. В основном я не понимал закрытий, поэтому поведение казалось странным. – user1821052

0

Они не «волшебным образом» получают доступ к обновлению. Они являются внутри myApp.User, поэтому они могут получить доступ к переменному местоположению.

Когда вы делаете myApp.User().getFirstName(), потому что внутри функции (области) находится getFirstName, она сможет обращаться к переменным, объявленным как внутри этой функции, так и вне этой функции.

function a(){ 
    var b = "hello"; 
    return { 
     setB: function(c){ b = c; }, 
     getB: function(){ return b; } 
    }; 
} 

var obj = new a(); 
obj.getB();   //hello 
obj.setB("new"); 
obj.getB();   //new 

В приведенном выше примере, getB и setB оба живут внутри объекта, и они могут получить доступ ко всем переменным внутри a() области.

0

посмотреть на то, что вы сделали здесь в первом примере

setFirstName: firstName 

setFirstName не является ссылкой на функцию «setFirstName», а переменная «FirstName» ... у вас нет доступа к function 'setFirstName'. Эта функция по-прежнему недоступна для вас, поэтому вы не можете изменить firstName, как хотите.

Это вне сферы действия - вы не вернули его, так что он доступен для внешнего мира, так сказать. Он не доступен «вне» области действия функции. Верните функцию() и примените «setFirstName», как показано ниже.

попробуйте это;

myApp.User = function() { 
    var firstName = 'Default', 
     lastName = 'Default'; 

    function setFirstName(name) { 
     firstName = name; 
    } 

    function setLastName(name) { 
     lastName = name; 
    } 

    function getFirstName() { 
     return firstName; 
    } 

    function getLastName() { 
     return lastName; 
    } 

    return { 
     getLastName: getLastName, 
     getFirstName: getFirstName, 
     setLastName: setLastName, 
     setFirstName: setFirstName 
    }; 
}(); 
myApp.User.setFirstName('bill'); 
myApp.User.getFirstName(); 
0
var User = function() { 
    var firstName = 'Default', 
     lastName = 'Default'; 

    return { 
     getLastName: function() { return lastName; }, 
     getFirstName: function() { return firstName; }, 
     setLastName: function(name) { lastName = name; }, 
     setFirstName: function(name) { firstName = name; }, 
     getName:  function() { return firstName + ' ' + lastName; } 
    }; 
}; 

var u = User(), 
    v = User(); 
console.log(u.getName() + ' - ' + v.getName()); 
// Outputs: 'Default Default - Default Default' 
u.setFirstName('Alice'); 
u.setLastName('Bob'); 
console.log(u.getName() + ' - ' + v.getName()); 
// Outputs: 'Alice Bob - Default Default' 
Смежные вопросы