【问题标题】:Simple JavaScript code does not work with nodejs简单的 JavaScript 代码不适用于 nodejs
【发布时间】:2015-01-25 18:10:23
【问题描述】:

我是一位经验丰富的 JavaScript 程序员,但刚刚开始学习

使用节点,我想读取目录的内容,并打印出只有特定扩展名的文件。目录和文件扩展名都将由命令行参数给出。

但是,当我解决这些难题时,我也想推动自己并探索 JavaScript 编程概念,所以我想创建一个 File 对象来存储有关文件的信息,并用它来解决问题。

正因为如此,我的方法过于复杂,而且我知道有更简单的方法可以做到这一点,但我只想要一个解决我当前问题的答案:

node.js为什么会抛出如下错误

this.baseName = /.+(?=\.[^.]+)/.exec(file)[0];
                                          ^
TypeError: Cannot read property '0' of null

在这段代码中:

function File(file){
  if (file instanceof File) return file;
  if (!(this instanceof File)) return new File(file);

  if (typeof file !== "string") throw new Error("Useful error." + typeof(file));

  this.fullName = file;

  /*vvvvvvvvvvvv  Important Bit  vvvvvvvvvvvvvv*/
  this.baseName = /.+(?=\.[^.]+)/.exec(file)[0];
  this.extension = /[^.]+(?=$)/.exec(file)[0];
}

File.prototype = {
  isOfType: function(ext){
    return ext === this.extension;
  }
}

var fs = require('fs');
var argv = process.argv;

fs.readdir(argv[2], function(err, list){
  var res = list.filter(function(element, index, array){
    var file = new File(element);
    return file.isOfType(argv[3]);
  });
  console.log(res);
});

但是,在 Chrome js 控制台中,它运行良好(当然是模拟 processfs 对象)。

对我(没有经验的我)来说,node 可能会犯几个错误:

  1. 没有正确处理正则表达式(我已经做过测试,这似乎很可能)
  2. 使用方括号在对象中查找键 '0',而不是在数组中查找索引 0

或者我可能会犯几个错误:

  1. 不理解 fs.readdir 及其必要的回调。
  2. 不了解 JavaScript 和 Node 中的构造函数之间可能存在的差异

请帮忙,我想要一个解决或解释我当前问题的答案,而不是解决它的答案。

谢谢。

【问题讨论】:

  • 找出:在您的违规行之前,请尝试 console.log(file, /.+(?=\.[^.]+)/.exec(file)) 并查看它的内容(为了理解您的代码,最好将其从 file 重命名为 fileName) .此外,您对 if (!(this instanceof File)) 的使用感到相当困惑,这不是您应该进行的测试。
  • @Mike'Pomax'Kamermans 我试过你的测试,我想我现在明白了:fs.readdir 还将目录名称放在返回的列表中(可能?),其中没有点或扩展名,因此找不到匹配项。会是这样吗?
  • 您正在测试的目录中是否有 .DS_Store 文件?正则表达式不会匹配任何东西,所以你会得到一个空值(它会抛出那个错误)。
  • @Mike'Pomax'Kamermans 事实上,这看起来很合理,这是您在抛出错误之前的测试输出:BefunExec-master null exec 没有返回任何内容。
  • 另外 - 使用路径模块来挑选文件名。不要使用临时正则表达式。

标签: node.js javascript regex node.js fs


【解决方案1】:

节点有一个built in 方法来检查有效文件

function File(file){
  if (file instanceof File) return file;
  if (!(this instanceof File)) return new File(file);

  if (typeof file !== "string") throw new Error("Useful error." + typeof(file));

  var stat = fs.statSync(file);

  if ( stat && stat.isFile() ) {

      this.fullName = file;

      /*vvvvvvvvvvvv  Important Bit  vvvvvvvvvvvvvv*/
      this.baseName = /.+(?=\.[^.]+)/.exec(file)[0];
      this.extension = /[^.]+(?=$)/.exec(file)[0];
  }
}

Node 还有一个built in 获取扩展名和路径名的方式

var path = require('path');

var basename = path.basename(file);

var extension = path.extname(file);

【讨论】:

  • 酷,我不知道。
【解决方案2】:

node.js为什么会抛出如下错误

this.baseName = /.+(?=\.[^.]+)/.exec(file)[0]; ^ TypeError:无法读取 null 的属性“0”

因为file不匹配正则表达式,所以exec返回null;然后你正在做null[0],它会抛出异常。例如,aa.... 伪目录之类的名称会发生​​这种情况。

使用 NodeJS 调试器或直接使用 console.log 文件`,您将看到导致问题的值。

【讨论】:

  • 是的,我没有意识到目录也包含在readdir 传递的列表中。似乎这是造成问题的原因。有什么方法可以快速巧妙地解决这个问题?
  • @theonlygusti:如果您认为基本名称是第一个 . 之前的任何内容,扩展名是 . 及其之后的任何内容,可能是 var result = /(.+?)(\.?.+)?/.exec(file); 和 @987654335 @ 和this.extension = result[1]; 你只会得到null 的空白字符串,但请注意.. 会给你. 作为名称和. 作为扩展名。或者只使用indexOfsubstring
  • 这似乎不起作用。如,错误发生了,但它没有正确匹配文件。
【解决方案3】:

这是因为任何与您的正则表达式不匹配的文件名,例如许多目录名称(包含在您的 list 变量中),然后将在此处返回 null:

/.+(?=\.[^.]+)/.exec(file)

所以你正在尝试做

null[0]

这是行不通的。

我通过简单地检查文件名中的句点来解决这个问题:

var file = (element.indexOf(".") > -1) ? new File(element) : false;
return (file) ? file.isOfType(argv[3]) : false;

在过滤器中,所以最终代码类似于:

fs.readdir(argv[2], function(err, list){
  var res = list.filter(function(element, index, array){
    var file = (element.indexOf(".") > -1) ? new File(element) : false;
    return (file) ? file.isOfType(argv[3]) : false;
  });
  for (var i = 0; i < res.length; console.log(res[i++]));
});

【讨论】:

    猜你喜欢
    • 2015-02-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-11-06
    • 2014-05-01
    • 1970-01-01
    • 2020-01-14
    • 2013-07-25
    相关资源
    最近更新 更多