在循环中声明的函数包含对变量的不安全引用 ESLint
Function declared in a loop contains unsafe references to variable(s) ESLint
我得到了以下函数,它接受一个对象和一个词,returns 一个对象,方法是用另一个字符串替换所有出现的传递的词。相同的函数将计算单词被替换的次数,并将其包含在替换的字符串中。
例如,考虑以下内容:
let noOfReplacements = 0;
const reg = new RegExp(`\bplease\b`, "gi");
const data = [
{
name: "please, I said please",
title: "Test One",
more: [
{
name: "another name",
title: "please write something. I said please."
}
]
},
{ name: "testTwo", title: "Test Two" },
{ name: "testThree", title: "Test Three" },
{ name: "testFour", title: "Test Four" }
];
const replace = (obj, reg) => {
for (const key in obj) {
if (typeof obj[key] === "object" && obj[key] !== null) {
replace(obj[key], reg);
} else if (key === "title") {
obj[key] = obj[key].replace(reg, function () {
noOfReplacements += 1;
return `repalced${noOfReplacements}`;
});
}
}
return obj;
};
const result = replace(data, reg)
console.log("number of replacements", noOfReplacements);
console.log("result", result);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
这很好用。但是,我收到 ESlint 警告:
Function declared in a loop contains unsafe references to variable(s) 'noOfReplacements'
在这种情况下,我如何安全地更新 noOfReplacements
?
我看过这个 ,但该解决方案的问题是它没有考虑单独的句子和单独替换的单词。所以在上面的例子中,虽然它会成功替换所有的单词,但它只会将计数增加 1,因为两个单词都在相同的 属性 中。因此,noOfReplacements
应为 2 时仍为 1。
您可以简单地按照规则的标题 (no-loop-func) 在循环外声明您的函数,然后在循环中调用它。
const replace = (object, reg) => {
const incrementAndReplace = () => {
noOfReplacements += 1;
return `repalced${noOfReplacements}`;
};
for (const key in object) {
if (typeof object[key] === 'object' && object[key] !== null) {
replace(object[key], reg);
} else if (key === 'title') {
object[key] = object[key].replace(reg, incrementAndReplace);
}
}
return object;
};
let noOfReplacements = 0;
const reg = /\bplease\b/gi;
const data = [
{
name: 'please, I said please',
title: 'Test One',
more: [
{
name: 'another name',
title: 'please write something. I said please.',
},
],
},
{name: 'testTwo', title: 'Test Two'},
{name: 'testThree', title: 'Test Three'},
{name: 'testFour', title: 'please Test Four'},
];
const replace = (object, reg) => {
const incrementAndReplace = () => {
noOfReplacements += 1;
return `repalced${noOfReplacements}`;
};
for (const key in object) {
if (typeof object[key] === 'object' && object[key] !== null) {
replace(object[key], reg);
} else if (key === 'title') {
object[key] = object[key].replace(reg, incrementAndReplace);
}
}
return object;
};
replace(data, reg);
console.log('number of replacements', noOfReplacements);
console.log('result', data);
无论如何,我总是会选择一种递归实现的、特定于标题的替换函数对任何外部范围都是不可知的方法。相反,它会 运行 在具有例如特征的绑定引用的上下文中。 a replacementCount
属性 将在内部进行跟踪。更新由 replacer 回调.
处理
下一个提供的递归实现还具有 Array
项目和 Object
条目特定迭代,以便仅处理 object 自己的属性,这与 OP 的 for...in
不同也迭代原型属性的循环。
function recursivelyReplaceTitleAndTrackBoundCount(data, regX) {
let { replacementCount: count } = this;
const boundRecursiveReplacer =
recursivelyReplaceTitleAndTrackBoundCount.bind(this);
const getTrackedCount = (/*match*/) => `repalced_${ ++count }`;
if (Array.isArray(data)) {
data.forEach(dataItem =>
boundRecursiveReplacer(dataItem, regX)
);
} else {
Object
.entries(data)
.forEach(([key, value]) => {
if (value && (typeof value === 'object')) {
boundRecursiveReplacer(value, regX);
} else if ((key === 'title') && regX.test(value)) {
data[key] = value.replace(regX, getTrackedCount);
this.replacementCount = count;
}
});
}
}
const data = [{
name: "please, I said please",
title: "Test One",
more: [{
name: "another name",
title: "please write something. I said please.",
}],
}, {
name: "testTwo",
title: "Test Two",
even: {
some: {
more: {
name: "another name",
title: "please write something. I said please.",
},
},
},
}, {
name: "testThree",
title: "Test Three",
}, {
name: "testFour",
title: "Test Four, if you ...please?",
}];
const tracker = { replacementCount: 0 };
recursivelyReplaceTitleAndTrackBoundCount
.call(tracker, data, /\bplease\b/gi);
const { replacementCount } = tracker;
console.log({ data, replacementCount });
.as-console-wrapper { min-height: 100%!important; top: 0; }
我得到了以下函数,它接受一个对象和一个词,returns 一个对象,方法是用另一个字符串替换所有出现的传递的词。相同的函数将计算单词被替换的次数,并将其包含在替换的字符串中。
例如,考虑以下内容:
let noOfReplacements = 0;
const reg = new RegExp(`\bplease\b`, "gi");
const data = [
{
name: "please, I said please",
title: "Test One",
more: [
{
name: "another name",
title: "please write something. I said please."
}
]
},
{ name: "testTwo", title: "Test Two" },
{ name: "testThree", title: "Test Three" },
{ name: "testFour", title: "Test Four" }
];
const replace = (obj, reg) => {
for (const key in obj) {
if (typeof obj[key] === "object" && obj[key] !== null) {
replace(obj[key], reg);
} else if (key === "title") {
obj[key] = obj[key].replace(reg, function () {
noOfReplacements += 1;
return `repalced${noOfReplacements}`;
});
}
}
return obj;
};
const result = replace(data, reg)
console.log("number of replacements", noOfReplacements);
console.log("result", result);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
这很好用。但是,我收到 ESlint 警告:
Function declared in a loop contains unsafe references to variable(s) 'noOfReplacements'
在这种情况下,我如何安全地更新 noOfReplacements
?
我看过这个 noOfReplacements
应为 2 时仍为 1。
您可以简单地按照规则的标题 (no-loop-func) 在循环外声明您的函数,然后在循环中调用它。
const replace = (object, reg) => {
const incrementAndReplace = () => {
noOfReplacements += 1;
return `repalced${noOfReplacements}`;
};
for (const key in object) {
if (typeof object[key] === 'object' && object[key] !== null) {
replace(object[key], reg);
} else if (key === 'title') {
object[key] = object[key].replace(reg, incrementAndReplace);
}
}
return object;
};
let noOfReplacements = 0;
const reg = /\bplease\b/gi;
const data = [
{
name: 'please, I said please',
title: 'Test One',
more: [
{
name: 'another name',
title: 'please write something. I said please.',
},
],
},
{name: 'testTwo', title: 'Test Two'},
{name: 'testThree', title: 'Test Three'},
{name: 'testFour', title: 'please Test Four'},
];
const replace = (object, reg) => {
const incrementAndReplace = () => {
noOfReplacements += 1;
return `repalced${noOfReplacements}`;
};
for (const key in object) {
if (typeof object[key] === 'object' && object[key] !== null) {
replace(object[key], reg);
} else if (key === 'title') {
object[key] = object[key].replace(reg, incrementAndReplace);
}
}
return object;
};
replace(data, reg);
console.log('number of replacements', noOfReplacements);
console.log('result', data);
无论如何,我总是会选择一种递归实现的、特定于标题的替换函数对任何外部范围都是不可知的方法。相反,它会 运行 在具有例如特征的绑定引用的上下文中。 a replacementCount
属性 将在内部进行跟踪。更新由 replacer 回调.
下一个提供的递归实现还具有 Array
项目和 Object
条目特定迭代,以便仅处理 object 自己的属性,这与 OP 的 for...in
不同也迭代原型属性的循环。
function recursivelyReplaceTitleAndTrackBoundCount(data, regX) {
let { replacementCount: count } = this;
const boundRecursiveReplacer =
recursivelyReplaceTitleAndTrackBoundCount.bind(this);
const getTrackedCount = (/*match*/) => `repalced_${ ++count }`;
if (Array.isArray(data)) {
data.forEach(dataItem =>
boundRecursiveReplacer(dataItem, regX)
);
} else {
Object
.entries(data)
.forEach(([key, value]) => {
if (value && (typeof value === 'object')) {
boundRecursiveReplacer(value, regX);
} else if ((key === 'title') && regX.test(value)) {
data[key] = value.replace(regX, getTrackedCount);
this.replacementCount = count;
}
});
}
}
const data = [{
name: "please, I said please",
title: "Test One",
more: [{
name: "another name",
title: "please write something. I said please.",
}],
}, {
name: "testTwo",
title: "Test Two",
even: {
some: {
more: {
name: "another name",
title: "please write something. I said please.",
},
},
},
}, {
name: "testThree",
title: "Test Three",
}, {
name: "testFour",
title: "Test Four, if you ...please?",
}];
const tracker = { replacementCount: 0 };
recursivelyReplaceTitleAndTrackBoundCount
.call(tracker, data, /\bplease\b/gi);
const { replacementCount } = tracker;
console.log({ data, replacementCount });
.as-console-wrapper { min-height: 100%!important; top: 0; }