2 回答

TA貢獻(xiàn)1815條經(jīng)驗(yàn) 獲得超6個(gè)贊
首先,booleanObject 和 eventObject 都需要在 if 語(yǔ)句之外聲明才能處于作用域內(nèi)。其次,如果您需要多次運(yùn)行executesMoreThanOnce,則需要在for循環(huán)中將isVarsInitOnce設(shè)置為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;
}
編輯
抱歉,我的錯(cuò),我沒(méi)有完全理解您的要求。查看以下內(nèi)容:
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貢獻(xiàn)1829條經(jīng)驗(yàn) 獲得超6個(gè)贊
我看過(guò)一些關(guān)于 JS 中的作用域和閉包的閱讀,我想我已經(jīng)找到了原始問(wèn)題中分解問(wèn)題的解決方案。
Aber Abou-Rahma 給出的答案并沒(méi)有解決我的問(wèn)題,因?yàn)槊看握{(diào)用executesMoreThanOnce().
這不是我想要的,因?yàn)槲抑幌朐谡{(diào)用該函數(shù)的第一個(gè)實(shí)例中初始設(shè)置變量(因?yàn)樵谖业膶?shí)際項(xiàng)目中,該函數(shù)executesMoreThanOnce()本質(zhì)上代表一個(gè)單擊事件回調(diào),需要在事件發(fā)生時(shí)保留數(shù)據(jù))被重新觸發(fā))。
我的解決方案使用立即調(diào)用函數(shù)表達(dá)式 (IIFE)。在 IIFE 范圍內(nèi)本地初始化變量,并在其返回的get方法中將變量釋放到全局范圍:
測(cè)試.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);
}
您現(xiàn)在可以在控制臺(tái)中看到該TEST.executesMoreThanOnce()函數(shù)開(kāi)始使用 IIFE 函數(shù)中本地定義的初始變量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}
我們現(xiàn)在還可以看到,一旦 i 值滿(mǎn)足函數(shù)中的某些條件TEST.executesMoreThanOnce(),布爾值就開(kāi)始切換,但更重要的是,這些變化在函數(shù)調(diào)用之間持續(xù)存在。
我仍然不確定我是否完全理解 IIFE 背后的抽象。但我可以在代碼中清楚地看到哪些變量屬于它們所使用的函數(shù)的范圍(提高可讀性)。這首先是我的目標(biāo)。
如果有人想糾正我的一些誤解,那么在我開(kāi)始嘗試將其應(yīng)用到我的項(xiàng)目之前,我們非常歡迎您的參與。
添加回答
舉報(bào)