英文:
Make Javascript Function Based on a Variable, Where Changing Variable Does Not Change Function
问题 {#heading}
以下是您要翻译的代码部分:
let x = "A";
function f() {
????
}
x = "B";
f(); // 打印出A,而不是B。
function f() {
console.log(x);
}
function f() {
let y = x + "";
console.log(y);
}
function g(y) {
return () => {
console.log(y);
};
}
let f = g(x);
function g() {
let y = x + "";
return () => {
console.log(y);
};
}
let f = g();
如您所需的,这些代码片段已被翻译。 英文:
I want to create a Javascript function based on the state of a variable at that time, and when the variable changes, the function should not change. Like I want something where like:
let x = "A";
function f() {
????
}
x = "B";
f(); // Prints A, not B.
Neither of these below worked:
function f() {
console.log(x);
}
function f() {
let y = x + "";
console.log(y);
}
These worked but I am worried that they access memory after it has been freed:
function g(y) {
return () => {
console.log(y);
};
}
let f = g(x);
function g() {
let y = x + "";
return () => {
console.log(y);
};
}
let f = g();
How do I do this right?
答案1 {#1}
得分: 2
您可以使用IIFE:
let x = "A";
const f = (() => {
let y = x;
return () => y;
})();
x = "B";
console.log(f());
英文:
You can use an IIFE:
<!-- begin snippet: js hide: false console: true babel: false -->
<!-- language: lang-js -->
let x = "A";
const f = (() => {
let y = x;
return () => y;
})();
x = "B";
console.log(f());
<!-- end snippet -->
答案2 {#2}
得分: 2
最简单的以编程方式实现这一点,而又不会有任何内存泄漏/全局声明(从技术上讲,取决于您在哪里声明 let x
),是以以下方式创建一个包含回调的闭包函数:
let x = "A";
let f = (function(x) {
return function() {
console.log(x);
};
})(x);
x = "B";
f(); // 打印出 A
这种工作方式是,它将一个引用存储为参数,而回调函数访问该引用以获取内部(lambda)函数的引用,而不是将引用指向内存中的 let x
声明。
请注意,IIFE(自调用)函数,在表达式末尾传递参数:
})(x); // 自调用
对于任何对此发生的原因感到好奇的人,这是因为 JavaScript 编译器采用了提升(hoisting),它将声明移动到代码片段中可能会出现在人眼中的顺序不一样的位置,而 OP 问题中的函数指向了一个已经被语句 x = 'B'
更改的内存引用。
英文:
The easiest way to achieve this programatically without having any memory leaks / global declarations (technically, depending where you declare let x
), is to create a closure over a callback with the function in a following fashion:
<!-- begin snippet: js hide: false console: true babel: false -->
<!-- language: lang-js -->
let x = "A";
let f = (function(x) {
return function() {
console.log(x);
};
})(x);
`x = "B";
f(); // Prints A
`
<!-- end snippet -->
The way this works, that it stores a reference as an argument and the callback accesses that reference for the inner (lambda) function instead of pointing reference to the let x
declaration in memory.
Note, the IIFE (self-invoked) function, at the end of the expression passing the argument
})(x); // self-invoked
To anyone curious why this happens in the first place, it's because JavaScript compiler employs hoisting, which moves declarations up so they are not in the order it may appear to a human eye in the code snipping and the function in the OP's question points to a memory reference which already is changed by the statement x = 'B'