2 回答
TA贡献1815条经验 获得超6个赞
首先,booleanObject 和 eventObject 都需要在 if 语句之外声明才能处于作用域内。其次,如果您需要多次运行executesMoreThanOnce,则需要在for循环中将isVarsInitOnce设置为false
let isVarsInitOnce = false;
function executesMoreThanOnce() {
const initVariables = function() {
console.log('runs once');
const bools = {
boolOne: false,
boolTwo: false,
boolThree: false
};
const events = {
clickEvent:
function(event) {
//do stuff
},
keyEvent:
function(event) {
//do other stuff
}
};
return {
bools: bools,
events: events
}
};
let booleanObject ; // declaring booleanObject outside the if statement
let eventObject ; // declaring eventObject outside the if statement
if (!isVarsInitOnce) {
isVarsInitOnce = true;
let vars = initVariables();
booleanObject = vars.bools;
eventObject = vars.events;
}
console.log('objects: ', booleanObject, eventObject);
//attempting to access initialised variable after function is executed more than once will cause an error.
//this is because the booleanObject is now undefined.
booleanObject.boolOne = true;
}
//runs 5 times
for (let i=0; i<5; i++) {// Will execute 5 times
executesMoreThanOnce();
isVarsInitOnce = false;
}
编辑
抱歉,我的错,我没有完全理解您的要求。查看以下内容:
JavaScript
// This will be the object that holds your variables
let vars;
function executesMoreThanOnce(obj) {
const initVariables = function(obj) {
console.log('runs once and obj = ' + obj);
if (obj == undefined) {
console.log('initialize once');
const bools = {
boolOne: false,
boolTwo: false,
boolThree: false
};
const events = {
clickEvent:
function(event) {
//do stuff
},
keyEvent:
function(event) {
//do other stuff
}
};
return (function(){
return {bools: bools,
events: events};
})();
}
// If vars object, "which we passed as argument", is initialized once before just return it
return vars;
};
vars = initVariables(vars);
let booleanObject = vars.bools;
let eventObject = vars.events;
console.log('objects: ', booleanObject, eventObject);
//attempting to access initialised variable after function is executed more than once will cause an error.
//this is because the booleanObject is now undefined.
// Yes you can now access the variables
booleanObject.boolOne = true;
}
//runs 5 times
for (let i=0; i<5; i++) {// Will execute 5 times
// Removed the bool flag and now passing the vars object as argument
executesMoreThanOnce(vars);
//executesMoreThanOnce();
//isVarsInitOnce = false;
}
TA贡献1829条经验 获得超6个赞
我看过一些关于 JS 中的作用域和闭包的阅读,我想我已经找到了原始问题中分解问题的解决方案。
Aber Abou-Rahma 给出的答案并没有解决我的问题,因为每次调用executesMoreThanOnce().
这不是我想要的,因为我只想在调用该函数的第一个实例中初始设置变量(因为在我的实际项目中,该函数executesMoreThanOnce()本质上代表一个单击事件回调,需要在事件发生时保留数据)被重新触发)。
我的解决方案使用立即调用函数表达式 (IIFE)。在 IIFE 范围内本地初始化变量,并在其返回的get方法中将变量释放到全局范围:
测试.js
const TEST = (function() {
let booleans = {
boolOne: false,
boolTwo: false,
boolThree: false
};
let events = {
clickEvent:
function(event) {
//do stuff
},
keyEvent:
function(event) {
//do other stuff
}
};
return {
executesMoreThanOnce: function(booleans, events, index) {
booleanObject = booleans;
eventsObject = events;
if (i == 2) {
booleanObject.boolTwo = true;
}
else if (i == 4) {
booleanObject.boolOne = true;
booleanObject.boolTwo = false;
}
console.log('booleanObject: ', booleanObject);
},
get variables() {
return {
booleans,
events
}
}
};
}());
for (var i=0; i<5; i++) {
TEST.executesMoreThanOnce(TEST.variables.booleans, TEST.variables.events, i);
}
您现在可以在控制台中看到该TEST.executesMoreThanOnce()函数开始使用 IIFE 函数中本地定义的初始变量TEST:
i = 0 | booleanObject: {boolOne: false, boolTwo: false, boolThree: false}
i = 1 | booleanObject: {boolOne: false, boolTwo: false, boolThree: false}
i = 2 | booleanObject: {boolOne: false, boolTwo: true, boolThree: false}
i = 3 | booleanObject: {boolOne: false, boolTwo: true, boolThree: false}
i = 4 | booleanObject: {boolOne: true, boolTwo: false, boolThree: false}
我们现在还可以看到,一旦 i 值满足函数中的某些条件TEST.executesMoreThanOnce(),布尔值就开始切换,但更重要的是,这些变化在函数调用之间持续存在。
我仍然不确定我是否完全理解 IIFE 背后的抽象。但我可以在代码中清楚地看到哪些变量属于它们所使用的函数的范围(提高可读性)。这首先是我的目标。
如果有人想纠正我的一些误解,那么在我开始尝试将其应用到我的项目之前,我们非常欢迎您的参与。
添加回答
举报