背景
用js写了几年前端程序,一直用extjs框架,最近学习了下angular觉得技术有必要升级换代了,于是就从把mxGraph从javascript转换为typescript开始了,本文介绍一下转换中常见问题。
转换步骤
1. 将*.js文件重命名为*ts文件;
2. 在vscode中逐个修改ts文件中的js代码:
2.1 将var 替换为 const /let ;
2.2 用class{ constructor() ... } 进行对象化封装;
2.3 消灭95%的prototype;
2.4 import依赖的外部类,vscode有一次全部import的功能;
2.4 一部分提示错误的window替换为globalThis;
2.5 用箭头函数=>替代大部分函数绑定;
2.6 对属性、函数参数和返回值进行类型标注;
2.7 用angular ng build/ ng serve进行编译和测试;
2.8 重新划分类及类所在文件以便消除循环引用(a import b,b import a);
2.9 对代码进行局部的重构和优化。
典型问题
1.消除prototype
在mxGraph中采用了prototype实现对象化,在typescript和es6中提供了class+constructor的对象化方式,两者之间的转换就是消除prototype的过程。
先将 “function 类名” 修改了 “class 类名{”,去掉 属性 前面的“类名.prototype.”,去掉方法前的 "类名.prototype." 和后面的"=function。修改前的js代码:
function mxCell(value, geometry, style)
{
= value;
(geometry);
(style);
if ( != null)
{
();
}
};
= null;
= function()
{
return ;
};
修改后的ts代码:
export class mxCell {
id = null;
constructor(value?, geometry?: mxGeometry, style?: string) {
= value;
(geometry);
(style);
if ( != null) {
();
}
}
getId() {
return ;
}
}
对于在其他文件中对“类名.prototype.方法”修改的部分,能够合并的合并到mxCell类,不能合并的通过增加子类来实现。
对于在其他文件中对“类名.prototype.属性"的访问,类型化中可以定义两个同名属性,其中一个为static,然后将“类名.prototype.属性"访问替换为“类名.属性"。
由于prototype对象化存在原型链污染问题,使得js代码难以分析和调试,尽量避免使用。
2.箭头函数的使用
js中函数通过绑定来保持函数内的this指向编译时的调用者,并传递arguments,箭头函数=>很适合用来替换这种绑定,但由于箭头函数不能传递arguments,因此在遇到函数内出现apply(this, arguments)时要将arguments替换为参数数组。对于绑定给非this对象,不适合用箭头函数。
= (this, function()
{
if ( != null)
{
(true);
}
});
//修改为
= ()=>
{
if ( != null)
{
(true);
}
});
中调用第三方js库
首先,需要在中包含js文件
"include": [
"src/assets/",
"src/assets/",
"src/assets/",
"src/assets/jscolor/"
]
然后在使用库的ts文件中声明js对象declare const jscolor; 之后jscolor就可以调用了。
效果
1. 代码重构后更加规范、易读,对象化代码更易于扩展;
2. 强类型后vscode帮助发现了很多编译错误;
3. 代码瘦身。