2015-10-27 3 views
1

Пытается следовать примеру в «Javascript: The Good Parts», создавая закрытие, которое нужно скрыть. В случае простой «счет» объект, который имеет баланс, который не может быть изменен непосредственно:Закрытие Javascript возвращает NaN?

<head> 
<script> 
    var myapp = {}; 
    var account = function() { 
     var value = 0; 
     return { 
      "account_name": "", 
      deposit: function (amount) { 
       value = this.value + amount; 
      }, 
      withdrawal: function (amount) { 
       value = this.value - amount; 
      }, 
      balance: function() { 
       return value; 
      } 
     } 
    }(); 
    myapp.account = account; 
</script> 
</head> 

<body> 
<script> 
    myapp.account.account_name = "Fred"; 
    myapp.account.deposit(100); 
    myapp.account.withdrawal(25); 

    document.writeln("<p>Account name = " + myapp.account.account_name + "</p>"); 

    document.writeln("<p>Balance = " + myapp.account.balance() + "</p>"); 


</script> 
</body> 

, который дает следующее:

имя учетной записи = Фред

Баланс = NaN

Wny NaN?

+2

BTW, обычно записывать сразу вызываемые функциональные выражения (IIFE) с окружающими скобками, такими как 'var f = (function() {...}())', так что легче видеть, что они скорее являются IIFE чем выражение простой функции, прежде чем вы дойдете до конца блока и увидите '...}()'. Я думал, что Крокфорд написал их так же. – RobG

+0

На самом деле нет, по крайней мере, в разделе о закрытии секции Крокфорда, о котором я говорил. Но, наверное, хорошая идея. – user1023110

ответ

1

Это происходит потому, что вы никогда не устанавливали this.value. В принципе, это может быть исправлено только ссылаться на closure'd переменная value:

var myapp = {}; 
var account = function() { 
    var value = 0; 
    return { 
     "account_name": "", 
     deposit: function (amount) { 
      value = value + amount; 
     }, 
     withdrawal: function (amount) { 
      value = value - amount; 
     }, 
     balance: function() { 
      return value; 
     } 
    } 
}(); 
myapp.account = account; 
myapp.account.account_name = "Fred"; 
myapp.account.deposit(100); 
myapp.account.withdrawal(25); 

$('p:nth-child(1)').text('Account name = ' + myapp.account.account_name); 
$('p:nth-child(2)').text('Balance = ' + myapp.account.balance()); 

JsFiddle

+0

Ага. Благодарю. Так что же означает это? Не функция, а объект, возвращаемый функцией? – user1023110

+0

да, в этом случае. В принципе, даже если 'this' ссылается на функцию, это все равно будет неопределенным, потому что' var value = 'не совпадает с' this.value = ' – Dethariel

+1

@ user1023110:' this' никогда не ссылается на функцию, если явно не задано так , Подробнее о 'this' из MDN: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/this или https://github.com/getify/You-Dont-Know -JS/blob/master/this% 20 &% 20object% 20prototypes/ch1.md –

0

Попробуйте: Я изменил немного битную код .... this.value изменения в единственное значение ..

<head> 
<script> 
    var myapp = {}; 
    var account = function() { 
     var value = 0; 
     return { 
      "account_name": "", 
      deposit: function (amount) { 
       value = value + amount; 
      }, 
      withdrawal: function (amount) { 
       value = value - amount; 
      }, 
      balance: function() { 
       return value; 
      } 
     } 
    }(); 
    myapp.account = account; 
</script> 
</head> 

<body> 
<script> 
    myapp.account.account_name = "Fred"; 
    myapp.account.deposit(100); 
    myapp.account.withdrawal(25); 

    document.writeln("<p>Account name = " + myapp.account.account_name + "</p>"); 

    document.writeln("<p>Balance = " + myapp.account.balance() + "</p>"); 


</script> 
</body> 
0

при назначении account в myapp, то scope отсутствует, положить var value вне функции

var myapp = {}; 
var value = 0; 
var account = (function(val){ 
     return{ 
      value: val, 
      "account_name": "", 
      deposit: function (amount) { 
       value = this.value + amount; 
      }, 
      withdrawal: function (amount) { 
       value = this.value - amount; 
      }, 
      balance: function() { 
       return value; 
      } 
     } 
    })(value); 
console.log(account); 
myapp.account = account; 


myapp.account.account_name = "Fred"; 
myapp.account.deposit(100); 
myapp.account.withdrawal(25); 

console.log("<p>Account name = " + myapp.account.account_name + "</p>"); 

console.log("<p>Balance = " + myapp.account.balance() + "</p>");