整日游离于C/C++/C#/TS/JS/pyton/SQL之间,还有一堆框架,整个人都快魔怔了! (学不动党表示人间不值得!)
备查笔记,记录一些Web脚本相关的语法和特性,随缘更新法
Q.typescript 使用类作为函数成员参数:
使用typeof关键字:
typeof
例子:
class Product { constructor(title:string) { this._title = title; } private _title:string; } function generatefactory(myClass:typeof Product):Product { return new myClass('product A'); }
模板函数中传递类名并约束构造函数:
function genrateFactory<T extends Product> (constructor:{ new(_title:string):Product,new():Product } ) { const x = new constructor('sss') }
Q.typescript *.d.ts和declare的使用:
TS基础
note:最近不怎么写前端了,记录一下备忘复查.,完全对typescript的module的概念不熟悉的,请预览: https://www.tslang.cn/docs/handbook/declaration-files/introduction.html
declare 关键字是用于变量的定义.
*.d.ts是typescript的声明文件.可以有多个.d.ts,ts会根据tsconfig.json的配置路径去解析
*.d.ts主要规定声明的作用域范围和模块的导出
声明分为:
1.类型定义声明
2.模块导出声明
1.类型定义声明:
因为ts是“强”类型语言(开发意义上),如果要使用未知变量需要先定义后使用.
例如在全局index.html里引用了的jquery 库,需要先
declare const $:any;
才可以在ts中使用.当然也可以在*.d.ts里全局声明,这样就不需要在每个*.ts的文件里声明了.
2.模块导出声明(为第三方库添加编写*.d.ts):
如果是第三方的es6类库且没有提供d.ts可能需要自己去编写(commandjs/umdjscommandjs/umdjs)
如adm-zip库为例:
declare module 'adm-zip' { export default class AdmZip { /** * * @param zipPath */ constructor( zipPath:string ); /** * */ public getEntries():Array<ZipEntry>; /** * * @param zipEntry * @param targetPath * @param maintainEntryPath * @param overwrite * @param callback */ public extractEntryToAsync( zipEntry:ZipEntry, targetPath:string, maintainEntryPath:boolean, overwrite:boolean, callback:(err:any)=>void):any; } export class ZipEntry { public entryName:string; public isDirectory:boolean; } }
3.重新扩展module 类的成员:
其他用法1:重载扩展/代码补全/加强可读性...
例如我在*.d.ts中定义了
declare namespace Electron { interface IpcRenderer { /** * * @param event * @param isTray */ send(event:'emp_onA', isTray:boolean):void; /** * * @param event * @param str */ send(event:'emp_onB', str:string):void; /** * * @param event * @param listener */ send(event:'emp_onC', listener:(arg:string)=>void ):void; } }
vs code 或web storm会进行相应的函数补全..(ts大法好)
如
Q.Javascript(js)的Promise的使用例子:
以XMLHttpRequest实现的ajax的Promise例子:
/** * ajax网络请求 */ function Req(url, method, data) { /** * @param {成功时,调用}} resolve * @param {失败时,调用} reject */ let inner = function (resolve, reject) { let req = new XMLHttpRequest(); /* jwt 表头setse设置 */ //req.setRequestHeader('Authorization', `Bearer token`); req.onload = ()=> { resolve( req.response); }; req.onerror = ()=> { reject(req.error); }; req.open(method, url, true); req.send(data); }; let promise = new Promise(inner); return promise; } Req(`https://www.baidu.com/`, `get`) .then((data)=> { console.log('success : ', data); }) .catch((error)=> { console.error('error : ', error); });
Q.javascript
(js)
模版字符串新语法糖:
跟C#的新字符串语法糖类似.
let testobj = {str : 'hello world.'}; let str = `$hi, ${testobj.str} `; console.log(str);
Q.javascript(js)的三个点(...)运算符:
1.spread运算:
语法糖,可快速向数组添加数组:
let arr = [{id :'a'},{id :'b'},{id :'c'}]; let arr1 = [{id :'d'},{id :'e'},{id :'f'}]; /** * arr新的数据为:[{"id":"a"},{"id":"b"},{"id":"c"},{"id":"d"},{"id":"e"},{"id":"f"}]; **/
2.可变函数参数,rest运算:
函数参数动态化:
跟c++的(...)和C#的params object[]一样的东西.都是用于可变参数(C++还可以用于可变模板类型数):
function test(...aaa){console.log(aaa);}
test('a',12312,{id :1231});
///aaa的数据结构为:["a", 12312, {id:1231}]
3.JavaScript的拷贝:
深拷贝要么用JSON.stringify和JSON.parse,要么自己扩展clone函数遍历属性或Lodash
现在可以用ES6的(...)语法,实现浅拷贝:
Note:仅单程引用,对于类似与{id: {name : 1111}};id还是并没有拷贝..以下还是得写clone...或转json
let t = {id: 1}; let t1 = {...t}; t.id = 10000; console.log('t:', t,'t1:' t1); /** * t = {id:10000};t1 = {id:1}; */
Q.TypeScript的Jquery和JqueryUI:
虽然有
@types/Jquery
@types/jqueryui
这俩个包,但是有些使用直接引用脚本比较方便
以Vue+TypeScript为例。
在Vue-Cli脚手架下的
首先,在Index.html 里添加
<!-- jquery ui --> <link rel="stylesheet" href="./static/lib/JqueryUI/jquery-ui.min.css"> <script src="./static/lib/JqueryUI/jquery-2.2.4.min.js"></script> <script src="./static/lib/JqueryUI/jquery-ui.min.js"></script> <!-- jquery ui -->
然后,需要用到的Ts或gobal.d.ts文件里添加以下代码(其他全局对象同理如Moment.js):
declare const $:any;
现在,就可以在TS里使用$进行Dom操作了