它们提供可变持久性的方式有几种?

时间:2019-05-17 17:28:03

标签: javascript node.js function variables

为函数中的变量提供持久性的不同模式有哪些,最适合这种特殊情况。

我知道提供持久性的方式包括:

// Method 1
let global_counter = 0;
function test () {
  global_counter++;
  // use global_counter
}

// Method 2
function test () {
        !test.function_counter ? test.function_counter = 0 : test.function_counter++;
  // use function_counter
}

// Other Methods

我试图远离全局变量。但是方法2似乎有点混乱。我有没有一种方法?

用例在下面,最后一个功能

日志

// Libraries
const fs = require('fs');

// API
getThings('_t/').then(() => {
})

// Accesses the file system and returns an array of files / folders
async function getThings (folder) { 
  const things = await fs.promises.readdir(folder);
  for(let i = 0; i < things.length; i++) {
    await getStats(things[i], folder);
  }
}

// Gets statistics for each file/folder
async function getStats (thing, folder) {
  const path = folder + thing;
  const stats = await fs.promises.stat(path);
  await checkForFolder(stats, thing, path);
}

// if the file/folder is a folder, recurse and do it again
async function checkForFolder(stats, thing, path){
  logThing(stats, thing, path);
  if (stats.isDirectory() ) {
    await getThings(path + '/');
  }
}

// Where should I put my counter that counts each time
// logThing is called?
function logThing(stats, thing, path){
  if (stats.isFile()) {
    console.log(thing);
  } else if (stats.isDirectory()) {
    console.log(thing + "*");
  }
}

4 个答案:

答案 0 :(得分:1)

在JavaScript中执行此操作的最常见方法之一(如果要避免明确包含状态和行为的对象)是使用闭包:

const myFunction = (() => { // this is the external function
  let someState = 0; 
  return () => { // this is the internal function, it can access someState
    return someState++; // the internal function can access this through a closure.
  };
})(); // invoke outside function

还请注意,最好不要具有全局状态-如果您执行someFunction.someVar而不是someVar,则示例2中的选项2仍然是全局的(以及我的答案中的此选项)它仍然是全局的-只是用一个更长的名称:]它之所以起作用,是因为函数恰好是对象本身。

答案 1 :(得分:1)

您说对了,您的第二选择似乎有些混乱。尽管如此,它完全在Javascript的工作方式之内。您正在将变量作为属性存储在函数对象中。它有效地起作用,并且阅读Javascript的人在看到Java语言时便确切知道它的含义。

以下是一个建议,可能会使其更清楚:

function test () {
        test.function_counter = (test.function_counter || 0) + 1;
        /* use the value */
}

关于性能:现代Javascript引擎非常有效地处理此处显示的语句以及您的语句。请记住,这种计算需要大约一纳秒的时间,而在最快的驱动器上文件打开至少需要几微秒的时间。不用担心。

要大规模处理文件,您可以研究Promise.all()作为协调大量文件操作的一种方式。

答案 2 :(得分:1)

另一个选择是创建一个对象,该对象在闭包中具有状态行为。这为您提供了常规javascript对象的所有灵活性以及轻松创建独立计数器的能力。您可以使用getter创建类似属性的函数,该函数返回当前值,然后将其递增。您也可以在不添加任何其他吸气剂的情况下获得价值。

function Counter(){
  let _count = 0 // count is private
  return {
    get 'count'(){ return _count },
    get 'add'(){ return _count++ }
  }
}  

// independent counters
let c = Counter()
let d = Counter()

while(c.add < 5){
  console.log('c:', c.count)
  if (c.count % 2) 
   console.log('d:   ', d.add)
}

答案 3 :(得分:1)

以下是三种最常用的方法及其特点:

// Method 1 - simple
let global_counter = 0;
function test () {
  global_counter++;
  // use global_counter
}

// Method 2 - concise and encapsulated
function test () {
        !test.function_counter ? test.function_counter = 0 : test.function_counter++;
  // use function_counter
}

// Method 3 - complex and encapsulated

const test = (() => {
  let counter = 0; 
  return () => {
    return count++;
  };
})();