[英]Inner function cannot access outer function variable after being changed
Yes, this question is similar with Inner function cannot access outer functions variable . 是的,这个问题与内部函数无法访问外部函数变量类似。 But it's not the same one.
但这不一样。 What confused me is "after being changed".
让我困惑的是“被改变后”。 Codes below maybe more intuitively.
下面的代码可能更直观。
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'
So this is what i want to figure out —— why the rewritten set_seq
method didn't change value of the private variable seq
in outer function? 所以这就是我要弄清楚的原因-为什么重写的
set_seq
方法没有更改外部函数中私有变量seq
的值?
Hope i could get some essential answers, thanks =) 希望我能得到一些基本的答案,谢谢=)
You are creating a new closure. 您正在创建一个新的关闭。 The returned function seqer.set_seq is a closure which can access the private variable seq.
返回的函数seqer.set_seq是一个闭包,可以访问私有变量seq。 But the newly defined seqer.set_seq is creating a new closure which cannot access the private variable, instead it creates a new global one
window.seq
但是新定义的seqer.set_seq正在创建一个无法访问私有变量的新闭包,而是创建了一个新的全局一个
window.seq
Try it: 试试吧:
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
It's actually another seq
variable. 它实际上是另一个
seq
变量。 When you run set_seq
for the first time, the seq
variable is already bounded to it, it does not read it directly from the function declaration. 第一次运行
set_seq
时, seq
变量已绑定到它,它不会直接从函数声明中读取它。
In other words, when you define your original function, an object with set_prefix
, set_seq
and gensym
is returned, and each of these function already have a reference to the seq
variable, which is defined in the function's closure. 换句话说,当您定义原始函数时,将返回带有
set_prefix
, set_seq
和gensym
的对象,并且这些函数中的每个函数都已经引用了seq
变量,该变量在函数的闭包中定义。 When you assign a new function to the returned object, it does not have the concept of the original seq
variable. 将新函数分配给返回的对象时,它没有原始
seq
变量的概念。
As @devnull69 has mentioned, you have created a closure and your seq is looking on global. 正如@ devnull69所提到的,您已经创建了一个闭包,并且您的seq正在全局查看。 If you want to modify your methods after the fact, maybe have a look at prototypes.
如果您想在事后修改方法,可以看看原型。
// 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'
Try using your var seq = 0 as global. 尝试使用var seq = 0作为全局变量。 ie Without var.
即无变种。
var prefix = ''; // scope :- local
seq = 0; // scope :- global
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.