如何覆盖函数的构造函数属性

我是JavaScript编程新手,我甚至不知道如何去问Google,所以我会详细描述我想实现的目标。

我使用node.js和xml2js模块为茉莉花创buildDataProvider类,parsing简单的XML文件:

<Tests> <Test name="test1"> <values>2,4,6</values> <expectations>1,2,3</expectations> </Test> <Test name="test2"> <values>8,10,12</values> <expectations>4,5,6</expectations> </Test> </Tests> 

我想要DataProvider构造函数立即parsingXML,并在this.testData显示结果。 脚本是:

 var fs = require('fs'), xml2js = require('xml2js'), util = require('util'); var DataProvider = function(dataPath) { this.dataPath = dataPath; this.testData; fs.readFile(this.dataPath, function(err, data) { var parser = new xml2js.Parser(); parser.parseString(data, function(err, result) { //console.log(util.inspect(result, false, null)); this.testData = result; }); }); }; 

我使用它如下所示:

 var dp = new DataProvider("C:\\data2.xml"); console.log(dp.testData); 

当我运行脚本>node script.js我收到undefined 。 当我取消注释console.log(util.inspect(result, false, null)); 我正在接受

 undefined { Tests: { Test: [ { '$': { name: 'test1' }, values: [ '2,4,6' ], expectations: [ '1,2,3' ] }, { '$': { name: 'test2' }, values: [ '8,10,12' ], expectations: [ '4,5,6' ] } ] } } 

所以一般它的工作原理,但如何将result分配给this.testData

这是否与this.testData范围连接?

JavaScript利用asynchronous范例很多,所以当你读取文件例如 – 你提供的函数作为callback将在自己的范围内执行。 this与范围有关,所以你会失去它。 在你试图引用this.testData实际上不会引用DataProvider对象,而是你提供给parseString的匿名函数的作用域。

所以有很less的方法可以克服,最简单的方法就是将thisvariables保存在上面的范围中,所以你可以引用它,比如self ,一些开发者更喜欢that

 var DataProvider = function(dataPath) { this.dataPath = dataPath; this.testData; var self = this; fs.readFile(this.dataPath, function(err, data) { var parser = new xml2js.Parser(); parser.parseString(data, function(err, result) { //console.log(util.inspect(result, false, null)); self.testData = result; }); }); }; 

或者使用.bind ,但是这里的缺点是它必须被使用两次(因为你有两个范围可以“穿越”

 var DataProvider = function(dataPath) { this.dataPath = dataPath; this.testData; fs.readFile(this.dataPath, function(err, data) { var parser = new xml2js.Parser(); parser.parseString(data, function(err, result) { //console.log(util.inspect(result, false, null)); this.testData = result; }.bind(this)); }.bind(this)); };