Javascript:重构现有代码以分离关注点,我们如何使用类/原型并从它自己的对象调用';方法?
我有一个网页,其中我展示了两个模型,每一个都在画布上使用Threejs 我想读一个本地文件,解析它,然后让它可以下载 我已经完成了,所有这些都是混合的,我的意思是逻辑既负责显示画布,也负责读取、解析和下载文件 我想将文件读取、解析和下载逻辑隔离到另一个类中。目前,我在一个名为InitCanvas.js的类中提取了canvas的show逻辑 代码如下:Javascript:重构现有代码以分离关注点,我们如何使用类/原型并从它自己的对象调用';方法?,javascript,file,object,refactoring,prototype,Javascript,File,Object,Refactoring,Prototype,我有一个网页,其中我展示了两个模型,每一个都在画布上使用Threejs 我想读一个本地文件,解析它,然后让它可以下载 我已经完成了,所有这些都是混合的,我的意思是逻辑既负责显示画布,也负责读取、解析和下载文件 我想将文件读取、解析和下载逻辑隔离到另一个类中。目前,我在一个名为InitCanvas.js的类中提取了canvas的show逻辑 代码如下: // this class handles the load and the canva for a nrrd // Using programm
// this class handles the load and the canva for a nrrd
// Using programming based on prototype: https://javascript.info/class
// This class should be improved:
// - Canvas Width and height
InitCanvas = function (IdDiv, Filename) {
this.IdDiv = IdDiv;
this.Filename = Filename
}
InitCanvas.prototype = {
constructor: InitCanvas,
init: function () {
this.container = document.getElementById(this.IdDiv);
// this should be changed.
this.container.innerHeight = 600;
this.container.innerWidth = 800;
//These statenments should be changed to improve the image position
this.camera = new THREE.PerspectiveCamera(60, this.container.innerWidth / this.container.innerHeight, 0.01, 1e10);
this.camera.position.z = 300;
let scene = new THREE.Scene();
scene.add(this.camera);
// light
let dirLight = new THREE.DirectionalLight(0xffffff);
dirLight.position.set(200, 200, 1000).normalize();
this.camera.add(dirLight);
this.camera.add(dirLight.target);
// read file
let loader = new THREE.NRRDLoader();
loader.load(this.Filename, function (volume) {
//z plane
let sliceZ = volume.extractSlice('z', Math.floor(volume.RASDimensions[2] / 4));
this.container.innerWidth = sliceZ.iLength;
this.container.innerHeight = sliceZ.jLength;
sliceZ.mesh.material.color.setRGB(0,1,1);
console.log('Our slice is: ', sliceZ);
scene.add(sliceZ.mesh);
}.bind(this));
this.scene = scene;
// renderer
this.renderer = new THREE.WebGLRenderer({alpha: true});
this.renderer.setPixelRatio(this.container.devicePixelRatio);
this.renderer.setSize(this.container.innerWidth, this.container.innerHeight);
// add canvas in container
this.container.appendChild(this.renderer.domElement);
},
animate: function () {
this.renderer.render(this.scene, this.camera);
}
}
因此,我们的想法是重构logic.js:
问题是:
1。为什么我们会得到:
TypeError: this.intoLines is not a function
这是指行:
let lineArr = this.intoLines(allText);
此外,为了解决此错误,我还尝试从对象传入函数,如下所示:
logic.js:
myFileReader = new MyFileReader();
myFileReader.readTextFile("columna01-es-latin1.txt", myFileReader.intoLines(), myFileReader.intoWords());
在我们的类myfilereader.js中,在readtTextFile中我们放了:
let lineArr = intoLines(allText);
let firstLineWords = intoWords(lineArr[0]);
let secondLineWords = intoWords(lineArr[1]);
我们的网络控制台告诉我们:
TypeError: text is undefined
我理解文本是未定义的,因为在logic.js中我们没有提供:
myFileReader.readTextFile("columna01-es-latin1.txt", myFileReader.intoLines(), myFileReader.intoWords());
但是我认为我们不能提供它,因为我们实际上是在请求myFileReader读取本地文件中的所有文本,并将其传递给intoLines()方法
2。为什么会发生这种情况,我们如何解决它?
谢谢你的帮助
编辑:
@Bergi建议之后的最终代码是:
function readTextFile(file) {
var rawFile = new XMLHttpRequest();
rawFile.open("GET", file, false);
rawFile.onreadystatechange = function () {
if (rawFile.readyState === 4) {
if (rawFile.status === 200 || rawFile.status == 0) {
allText = rawFile.responseText;
console.log('The complete text is', allText);
let lineArr = intoLines(allText);
let firstLineWords = intoWords(lineArr[0]);
let secondLineWords = intoWords(lineArr[1]);
console.log('Our first line is: ', lineArr[0]);
let atlas = {};
for (let i = 0; i < firstLineWords.length; i++) {
console.log(`Our ${i} word in the first line is : ${firstLineWords[i]}`);
console.log(`Our ${i} word in the SECOND line is : ${secondLineWords[i]}`);
atlas[firstLineWords[i]] = secondLineWords[i];
}
console.log('The atlas is: ', atlas);
let atlasJson = JSON.stringify(atlas);
console.log('Atlas as json is: ', atlasJson);
download(atlasJson, 'atlasJson.txt', 'text/plain');
}
}
};
rawFile.send(null);
}
function download(text, name, type) {
var a = document.getElementById("a");
var file = new Blob([text], {type: type});
a.href = URL.createObjectURL(file);
a.download = name;
}
function intoLines(text) {
// splitting all text data into array "\n" is splitting data from each new line
//and saving each new line as each element*
var lineArr = text.split('\n');
//just to check if it works output lineArr[index] as below
return lineArr;
}
function intoWords(lines) {
var wordsArr = lines.split('" "');
return wordsArr;
}
函数readTextFile(文件){
var rawFile=new XMLHttpRequest();
打开(“获取”,文件,错误);
rawFile.onreadystatechange=函数(){
if(rawFile.readyState==4){
if(rawFile.status==200 | | rawFile.status==0){
allText=rawFile.responseText;
console.log('完整文本为',所有文本);
让lineArr=输入行(所有文本);
让firstLineWords=intoWords(lineArr[0]);
让secondLineWords=intoWords(lineArr[1]);
log('我们的第一行是:',lineArr[0]);
让atlas={};
for(设i=0;i
我还研究了:
原型:
为什么会发生这种情况,我们如何解决它
看
作为一门新课,我尝试了以下几点
这是你的问题。根本没有理由使用类构造,您不会实例化它并保留对象上的数据
是的,将readTextFile、download、intoArray、intoWords提取到自己的模块中,在自己的文件中,这是一个好主意。但是没有理由使用(空的!)构造函数和原型,只使用普通函数就可以了(而且您在访问实例方法时也不会遇到上述问题)。谢谢@Bergi我已经按照您的建议做了,这是正确的,普通函数在这里很好。
TypeError: text is undefined
myFileReader.readTextFile("columna01-es-latin1.txt", myFileReader.intoLines(), myFileReader.intoWords());
function readTextFile(file) {
var rawFile = new XMLHttpRequest();
rawFile.open("GET", file, false);
rawFile.onreadystatechange = function () {
if (rawFile.readyState === 4) {
if (rawFile.status === 200 || rawFile.status == 0) {
allText = rawFile.responseText;
console.log('The complete text is', allText);
let lineArr = intoLines(allText);
let firstLineWords = intoWords(lineArr[0]);
let secondLineWords = intoWords(lineArr[1]);
console.log('Our first line is: ', lineArr[0]);
let atlas = {};
for (let i = 0; i < firstLineWords.length; i++) {
console.log(`Our ${i} word in the first line is : ${firstLineWords[i]}`);
console.log(`Our ${i} word in the SECOND line is : ${secondLineWords[i]}`);
atlas[firstLineWords[i]] = secondLineWords[i];
}
console.log('The atlas is: ', atlas);
let atlasJson = JSON.stringify(atlas);
console.log('Atlas as json is: ', atlasJson);
download(atlasJson, 'atlasJson.txt', 'text/plain');
}
}
};
rawFile.send(null);
}
function download(text, name, type) {
var a = document.getElementById("a");
var file = new Blob([text], {type: type});
a.href = URL.createObjectURL(file);
a.download = name;
}
function intoLines(text) {
// splitting all text data into array "\n" is splitting data from each new line
//and saving each new line as each element*
var lineArr = text.split('\n');
//just to check if it works output lineArr[index] as below
return lineArr;
}
function intoWords(lines) {
var wordsArr = lines.split('" "');
return wordsArr;
}