[英]Inner function cannot access outer function variable after being changed
是的,這個問題與內部函數無法訪問外部函數變量類似。 但這不一樣。 讓我困惑的是“被改變后”。 下面的代碼可能更直觀。
var serial_maker = function() {
var prefix = '',
seq = 0;
return {
set_prefix: function(p) {
prefix = String(p);
},
set_seq: function(s) {
seq = s;
},
gensym: function() {
var result = prefix + seq;
seq += 1;
return result;
}
};
};
var seqer = serial_maker();
seqer.set_prefix('Q');
seqer.set_seq(1000);
seqer.gensym(); // 'Q1000'
// Rewrite set_seq method
seqer.set_seq = function() {
seq = 2000;
};
seqer.set_seq();
seqer.gensym(); // 'Q1001', which was expected 'Q2000'
所以這就是我要弄清楚的原因-為什么重寫的set_seq
方法沒有更改外部函數中私有變量seq
的值?
希望我能得到一些基本的答案,謝謝=)
您正在創建一個新的關閉。 返回的函數seqer.set_seq是一個閉包,可以訪問私有變量seq。 但是新定義的seqer.set_seq正在創建一個無法訪問私有變量的新閉包,而是創建了一個新的全局一個window.seq
試試吧:
var serial_maker = function() {
var prefix = '',
seq = 0;
return {
set_prefix: function(p) {
prefix = String(p);
},
set_seq: function(s) {
seq = s;
},
gensym: function() {
var result = prefix + seq;
seq += 1;
return result;
}
};
};
var seqer = serial_maker();
seqer.set_prefix('Q');
seqer.set_seq(1000);
seqer.gensym(); // 'Q1000'
// Rewrite set_seq method
seqer.set_seq = function() {
seq = 2000;
};
seqer.set_seq();
seqer.gensym(); // Q1001 is correct!
console.log(window.seq); // 2000
它實際上是另一個seq
變量。 第一次運行set_seq
時, seq
變量已綁定到它,它不會直接從函數聲明中讀取它。
換句話說,當您定義原始函數時,將返回帶有set_prefix
, set_seq
和gensym
的對象,並且這些函數中的每個函數都已經引用了seq
變量,該變量在函數的閉包中定義。 將新函數分配給返回的對象時,它沒有原始seq
變量的概念。
正如@ devnull69所提到的,您已經創建了一個閉包,並且您的seq正在全局查看。 如果您想在事后修改方法,可以看看原型。
// Constructor
var Serial_maker = function() {
var prefix = '', seq = 0;
};
// Define the methods
Serial_maker.prototype.set_prefix = function(p) {
prefix = String(p);
};
Serial_maker.prototype.set_seq = function(s) {
seq = s;
}
Serial_maker.prototype.gensym = function() {
var result = prefix + seq;
seq += 1;
return result;
}
// Create the object with new
var seqer = new Serial_maker();
seqer.set_prefix('Q');
seqer.set_seq(1000);
seqer.gensym();
// You can modify the methods on the
// constructor's prototype anywhere in the code
// and it will apply to all objects that were created
// with it.
Serial_maker.prototype.set_seq = function(s) {
seq = 2000;
}
seqer.set_seq();
console.log(seqer.gensym()); // Output is 'Q2000'
嘗試使用var seq = 0作為全局變量。 即無變種。
var prefix = ''; // scope :- local
seq = 0; // scope :- global
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.