[英]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.