大家好,我卡颂。
在布达佩斯2022 JSConf会议上,tc39(ES标准委员会)成员「Gil Tayar」介绍了一份当前仍处于stage 1阶段的提案 —— Type Annotations,意在让原生JS支持类型注解。
换句话说,如果提案通过,很多.ts文件将后缀改为.js后就能直接在浏览器中运行。
一份tc39提案通常会经历5个阶段:
所以Type Annotations当前仍处于「接受审议」的状态。
但是提案发起者「Gil Tayar」对这份提案的通过很有信心,本文我们来聊聊这份提案的相关内容。
根据20年、21年state of JS的统计,「静态类型」高票当选「JS中当前最欠缺的功能」。
同时,在Github报告中,TS被列为「第四大最常用的语言」
所以,对前端工程师来说,「类型注解」需求很大。
那么,既然已经有了TS,为什么还需要原生JS支持「类型注解」呢?
通常来说,从「开发者编写的源代码」到「线上生产环境代码」间需要经过「代码编译」。
「代码编译」主要包括两个步骤:
所谓「类型擦除」,是指擦除代码中的「类型注解」,让其变成符合原生JS规范的代码,比如:
// 擦除前
function add(a: number, b: number): number {
return a + b;
}
// 擦除后
function add(a, b) {
return a + b;
}
随着时间的推移,各主流浏览器兼容性越来越好,「步骤1」在可预见的未来重要性会逐渐降低。
对于TS开发者,从「源代码」到「线上生产环境代码」间可能只需要「类型擦除」。
如果原生JS支持「类型注解」,就能省去「类型擦除」对应的编译流程,让代码更容易在宿主环境执行。
这份提案的目的,并不是另起炉灶,独立实现一套原生 JS 的类型注解。而是与「TS团队」合作,提出一套合适的规范。
新的规范与「TS规范」的关系类似下图:
一方面,Type Annotations提案从TS中借鉴了很多特性,这就是图中相交的部分。
你可以到grammar-conventions看到规范当前定义的类型
另一方面,TS迭代速度很快,新的特性产出很快。而Type Annotations作为JS语言的一部分,迭代会更加保守,所以TS中一些特性在Type Annotations中并不支持。
此外,TS中一些结构(比如Enums、Namespaces)存在运行时的语义,Type Annotations也不会支持。
这些就是TS中存在,而Type Annotations中不存在的部分。
最后,Type Annotations设计的初衷并不是与TS强绑定,而仅仅是提供一套类型规范,开发者编写代码时的「类型检查」还是由各种类型检查器(比如TS、Flow)实现。
所以,Type Annotations还有一部分特性是TS当前未定义的,这也是为了规范更广泛的适用性考虑的,也就是图中Type Annotations存在,而TS不存在的部分。
这部分特性需要TS后续实现,这也是为什么Type Annotations要与TS团队合作的一大原因。
如果Type Annotations最终出现在ES20xx版中,届时开发者编写代码的步骤是:
对于如下原生JS代码,如果开发者传入了错误的类型,JS会报错么?
function add(a: number, b: number): number {
return a + b;
}
// 错误的类型传参
add('KaSong', 123);
答案是:不会。
Type Annotations仅仅是一套规范,该规范由各种类型检查器执行。
JS的宿主环境(比如浏览器)在执行「带类型声明的JS代码」时,会忽略类型声明。
有同学可能会问:就为了减少编译时「类型擦除」这一步,就提出原生类型规范,有必要么?
甚至当Type Annotations落地后,开发者上线前在进行代码压缩时,「类型擦除」也会作为「代码压缩」的职责之一。
从这个角度看,甚至没有减少编译时的工作量。
所以提出原生的类型规范,有必要么?
前端的发展实际是一个「努力去编译时流程」的过程。
比如,编译时代码需要降级,需要polyfill?随着IE11停止服务,主流浏览器纷纷跟进标准落地,降级与polyfill的需求逐渐变少。
再比如,代码需要打包?随着ESM规范落地,在当前,至少在开发环境中代码已经不需要打包(使用Vite)。
Type Annotations的出现,就是遵循「努力去编译时流程」这一趋势的产物。
从这个角度看,还是很有必要的。
来源: 魔术师卡颂
在JavaScript中存在这样两种原始类型:Null与Undefined。这两种类型常常会使JavaScript的开发人员产生疑惑,在什么时候是Null,什么时候又是Undefined?Undefined类型只有一个值,即undefined。当声明的变量还未被初始化时,变量的默认值为undefined。
主要介绍了JS中检测数据类型的几种方式,typeof运算符用于判断对象的类型,但是对于一些创建的对象,它们都会返回\'object\',有时我们需要判断该实例是否为某个对象的实例,那么这个时候需要用到instanceof运算符
对于object和number、string、boolean之间的转换关系,ToPrimitive是指转换为js内部的原始值,如果是非原始值则转为原始值,调用valueOf()和toString()来实现。
Undefined类型表示未定义,它的类型只有一个值为undefined。undefined和null有一定的表意差别。非整数的Number类型无法使用 == 或 === 来比较,因为 JS 是弱类型语言,所以类型转换发生非常频繁
近在做项目代码重构,其中有一个要求是为代码添加智能提示和类型检查。智能提示,英文为 IntelliSense,能为开发者提供代码智能补全、悬浮提示、跳转定义等功能,帮助其正确并且快速完成编码。
基本类型:按值访问,可以操作保存在变量中实际的值;引用类型数据存在堆内存,而引用存在栈区,也就是说引用类型同时保存在栈区和堆区,关于==的执行机制,ECMASript有规范,因为==前后的值交换顺序,返回的值也是一样的,所以在此对规范做出如下总结
JavaScript 是一种弱类型或者说动态类型语言。所以你不用提前声明变量的类型,在程序运行时,类型会被自动确定,你也可以使用同一个变量保存不同类型的数据。
js的值传递和引用(地址)传递:js的5种基本数据类型 number,string,null,undefined,boolean 在赋值传递时是值传递,js的引用数据类型(object,array,function)进行引用传递,其实底层都是对象。
JS中所有的值都可以转换成布尔类型 使用Boolean()或者 !!(两个感叹号),JS中所有的值都可以转换成数字类型,使用Number()或+。数字类型转换场景目的只有一个,用于计算,将后台传递的数据,从字符串转换为数字并参与计算
众所周知,JS在很多情况下会进行强制类型转换,其中,最常见两种是:1.使用非严格相等进行比较,对==左边的值进行类型转换2.在if判断时,括号内的值进行类型转换,转化为布尔值
内容以共享、参考、研究为目的,不存在任何商业目的。其版权属原作者所有,如有侵权或违规,请与小编联系!情况属实本人将予以删除!