对 Javascript 对象使用纯函数
Using pure function with Javascript object
假设我有这样的代码:
function example() {
const obj = {};
for (let i = 0; i < 10; i++) {
for (let j = 0; j< 10; j++) {
if (obj[i] == undefined) {
obj[i] = 0;
}
if (obj[j] == undefined) {
obj[j] = 0;
} else {
obj[i] += i;
obj[j] += j;
}
}
}
}
在这里你可以看到:
if (obj[i] == undefined) {
obj[i] = 0;
}
我检查 i
是否不在 obj
我将 obj
内的键 i
分配为 0 否则我什么都不做,我用 [=19= 进行采样].
代码是重复的,我不想重复我自己,这是不好的做法,所以我做了另一个函数来申请 i
和 j
像这样:
function initObjWithValue(obj, keys) {
for (const key of keys) {
if (obj[key] === undefined) {
obj[key] = 0;
}
}
}
这个功能很容易理解吧?它的第一个参数是一个对象,第二个参数是要检查的键数组。现在我可以像这样重构我的代码:
function example() {
const obj = {};
for (let i = 0; i < 10; i++) {
for (let j = 0; j< 10; j++) {
initObjWithValue(obj, [i, j]);
obj[i] += i;
obj[j] += j;
}
}
}
代码更清晰,但正如您在我的函数 initObjWithValue
中看到的那样,它发生了变异 obj
,我认为这并不好。这是来自 Wiki 页面的引用:
In computer programming, a pure function is a function that has the following properties:
Its return value is the same for the same arguments (no variation with local static variables, non-local variables, mutable reference arguments or input streams from I/O devices).
然后就卡在这了,怎么才能不重蹈覆辙,实现纯功能呢?
您可以改为创建 initObjectWithValue
return 一个新对象,然后您可以将其与当前的 obj
合并。这样,您所做的就是从 obj
读取数据,而不是在 initObjectWithValue
:
内对其进行修改
function initObjWithValue(obj, keys) {
const tmp = {};
for (const key of keys) {
if (!(key in obj)) {
tmp[key] = 0;
}
}
return tmp;
}
function example() {
const obj = {};
for (let i = 0; i < 10; i++) {
for (let j = 0; j< 10; j++) {
Object.assign(obj, initObjWithValue(obj, [i, j])); // merge the return with current object
obj[i] += i;
obj[j] += j;
}
}
return obj;
}
console.log(example());
而不是检查
(obj[i] == undefined)
写
(typeof obj[i] == undefined)
假设我有这样的代码:
function example() {
const obj = {};
for (let i = 0; i < 10; i++) {
for (let j = 0; j< 10; j++) {
if (obj[i] == undefined) {
obj[i] = 0;
}
if (obj[j] == undefined) {
obj[j] = 0;
} else {
obj[i] += i;
obj[j] += j;
}
}
}
}
在这里你可以看到:
if (obj[i] == undefined) {
obj[i] = 0;
}
我检查 i
是否不在 obj
我将 obj
内的键 i
分配为 0 否则我什么都不做,我用 [=19= 进行采样].
代码是重复的,我不想重复我自己,这是不好的做法,所以我做了另一个函数来申请 i
和 j
像这样:
function initObjWithValue(obj, keys) {
for (const key of keys) {
if (obj[key] === undefined) {
obj[key] = 0;
}
}
}
这个功能很容易理解吧?它的第一个参数是一个对象,第二个参数是要检查的键数组。现在我可以像这样重构我的代码:
function example() {
const obj = {};
for (let i = 0; i < 10; i++) {
for (let j = 0; j< 10; j++) {
initObjWithValue(obj, [i, j]);
obj[i] += i;
obj[j] += j;
}
}
}
代码更清晰,但正如您在我的函数 initObjWithValue
中看到的那样,它发生了变异 obj
,我认为这并不好。这是来自 Wiki 页面的引用:
In computer programming, a pure function is a function that has the following properties: Its return value is the same for the same arguments (no variation with local static variables, non-local variables, mutable reference arguments or input streams from I/O devices).
然后就卡在这了,怎么才能不重蹈覆辙,实现纯功能呢?
您可以改为创建 initObjectWithValue
return 一个新对象,然后您可以将其与当前的 obj
合并。这样,您所做的就是从 obj
读取数据,而不是在 initObjectWithValue
:
function initObjWithValue(obj, keys) {
const tmp = {};
for (const key of keys) {
if (!(key in obj)) {
tmp[key] = 0;
}
}
return tmp;
}
function example() {
const obj = {};
for (let i = 0; i < 10; i++) {
for (let j = 0; j< 10; j++) {
Object.assign(obj, initObjWithValue(obj, [i, j])); // merge the return with current object
obj[i] += i;
obj[j] += j;
}
}
return obj;
}
console.log(example());
而不是检查
(obj[i] == undefined)
写
(typeof obj[i] == undefined)