如何覆盖函数的构造函数属性
我是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的方法可以克服,最简单的方法就是将this
variables保存在上面的范围中,所以你可以引用它,比如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)); };