Typescript学习前奏---强类型与弱类型,静态类型和动态类型

强类型与弱类型

再具体介绍JavaScript的类型系统的问题之前,我先来解释两组在区分不同编程语言时经常提及的名词,分别是强类型和弱类型,还有就是静态类型动态类型,那他们呢,分别是从类型,安全和类型检查这两个维度去区分了不同的编程语言,首先我们来看类型安全的角度,那从类型安全角度来说,编程语言作为强类型和弱类型,那这种强弱类型的概念最早是1974年的时候,美国有两个计算机专家提出的,那当时呢,对强类型这个概念的定义,就是在语言层面就限制我们函数的。实参类型必须要跟形参类型完全不同,例如呢,有一个foo函数,那他需要接受一个整型的参数,我们去调取的时候就不允许直接去传入一个其他类型的值,那么可以选择在传入之前呢,先将我们这个值转换成一个整型的数字,然后再进入,而弱类型则完全相反,在语言方面并不会去限制我们实参的类型,即便说我们这个函数需要的参数是整型的数字,我在这时仍然可以传入任意类型的数据,语法上是不会报错的,在运行中可能出现问题与法律问题,由于这种强弱之分呢,根本不是某一个权威机构的利益,而且呢,当时这两位计算机的专家也没有给出一个具体的规则,所以说就导致了后人对这种鉴定方式的细节出现了一些不一样的理解,但是整体上大家的鉴定方式都在描述强类型的,他是有更强的类型约束,而弱类型呢,他几乎没有什么类型约束,那我个人比较同意一个说法,就是强类型语言当中,不允许有任意的隐式类型转换,而在弱类型语言当中,和允许任意的隐式类型数据转换.例如我这需要一个数字,你这放一个字符串也是可以的.

总结

这里我们总结一下强类型和弱类型,这两种类型之间的差异呢,就是不允许任何的隐式类型转换,而弱类型,它是比较随意的,它可以任意的隐式类型转换,当然这只是我理解的一种强类型的激励方式,并不是一个说法,业界呢,也根本没有一个说法,你可以根据你自己的理解去做一个定义,那对于你可能会想到我们在代码中的变量类型可以随时改变主意的特点,那其实这并不是强弱类型之间的区别,我就拿python来说呢,它是一门强类型语言,但是呢,它的变量仍然是可以随时改变类型的特点,在很多资料中可能都表示有些不太妥当,他们在说python是一门弱类型语言,其实不是这样的。

静态类型和动态类型

那从类型安全的角度强类型和弱类型之分,在类型检查的角度,我们可以将变成语言分为静态类型语言和动态类型语言,关于静态语言和动态语言之间的差异呢,并没有什么争议,大家都很统一,对于静态语言最主要表现就是一个变量,声明时它的类型就明确的,而且呢,在变量声明过后它的类型就不允许被修改了,那相反,动态类型语言的特点呢,就是在运行阶段才能够明确一个类型,而且变量的类型也可以随时发生变化

var foo = 10;//声明是默认是number类型
foo = 'cc';//转换成了字符串类型

我们可以说在动态类型当中的变量是没有类型的,变量当中所存放的值是有类型的,那JavaScript呢,就是一门标准的动态类型语言呢,总的来说从类型安全角度一般将编程语言分为强类型和弱类型,两者之间的区别就是是否允许随意的隐式类型转换,那从类型检查的角度分为静态类型和动态类型,它两者之间的区别就是是否允许修改变量的类型。

以下常用语言在这两种维度下的表现

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-TurNXQCL-1597675404562)(6FF54E90672B47AD85A4FDE6C7E8191B)]

JavaScript类型系统的特征

由于JavaScript是一门弱类型而且是动态类型的语言,本身的系统是非常薄的,甚至也可以说扎实的根本就没有类型系统,那这种语言的特征,用一个比较流行的词来说,就是任性,因为他几乎没有任何类型限制,所以我们JavaScript这门语言呢,也是极其灵活多变的,但是在这种灵活多变的表象背后,丢失掉的就是类型系统的可靠性,我们在代码当中每每遇到变量都要担心他到底是不是我们想要的类型,整体感受用另外一个流行词来说就是不靠谱.

可能有人会问为什么JavaScript不能设计成强类型或者静态类型这种更靠谱的语言呢?

这个原因自然跟詹姆斯的背景有关,首先,在早前根本就没想到JavaScript的应用会发展到今天,这种规模,那最早的JavaScript应用他根本不会太复杂,需求都非常简单,很多时候几百行代码甚至是几十行就搞定了,那在这种一眼就能够看到头的这种情况下,类型系统限制呢,就显得很多余或者是很麻烦的;

其次呢,JavaScript是一门脚本语言,那脚本语言的特点就是不需要编译,就直接在运行中去运行,换句话说,JavaScript他是没有编译环节的,那即便把它设计成一个静态类型,语言也没有意义,因为静态类型语言需要在编译阶段去做类型检查,而JavaScript没有编译环境,根据以上这些原因JavaScript成为了一门灵活的弱类型/动态类型语言.

在现在大规模应用的情况下,JavaScript的优势变成了短板!

弱类型的问题

  • 接下来我们具体来看,JavaScript弱类型语言在去应对大规模开发时,有可能会出现一些常见问题,当然我们这里所列的问题呢,只是冰山一角,不过他们也都能反映出一些问题,那首先我们来看第一个例子呢,
// javascript 弱类型产生的问题
const obj = {}
// obj.foo();//我们去调用这个方法,那很明显的对象当中并不存在这样的方法,但是呢,在语言的语法方面,这样写是可行的

我们去定义这个obj对象,然后呢,我们去调用foo这个方法,那很明显的对象当中并不存在这样的方法,但是呢,在语言的语法方面,这样写是可行的,只是呢,我是把代码放在node环境中去运行,就会报出一个错误,那也就是说,在JavaScript的这种弱类型语言当中,我们就必须要等到运行阶段。才能够去发现代码当中的一些类型异常,而且如果这里并不是立即去执行去做方法,而是在某一个特定的时间才去执行,例如

setTimeout(() => {
    obj.foo()
}, 1000000);

那程序呢,在刚刚启动运行时还没有办法去发现异常,一直等到代码执行了,才有可能去抛出这样一个异常,那也就是说,如果我们在测试的过程中没有测试到这一行代码,那这样的隐患就会被留在我们的代码当中。

  • 而如果是强类型语言的话,那在这里我们直接去调用一个不存在成员,这里语法上就会报出错误,根本不用等到我们去运行代码,我们再来看第二个例子呢
function sum(a,b){
    return a + b;
}
console.log(sum(100,100))
console.log(sum(100,'100'));//报错

sum就是去计算这两个数的和,我们玩的是两数的话,结果自然是正常的,但是如果我们候传入的是字符串,那这种情况下,我们这个函数的作用就完全发生了变化,那他会返回我们对两个字符串连接过后的结果,那这就是因为类型不确定所造成的一个最典型的问题呢,有人说我们可以通过自己的约定去规避这个问题,的确通过约定方式是可以规避这个问题,但是你要知道约定是根本没有任何保障的,特别是在多人集中开放情况下,我们根本没办法保证每个人都能遵循所有原因,而我们用强类型语言的话,那这种情况就会彻底避免掉,因为在强类型语言当中,如果我们要求传入的数字,那你传入的是其他类型的值,在语法上就行不通。

  • 那再来看第三个例子,
const obj = {}
obj[true] = 100
console.log(obj['true'])

这里呢,我们先去创建一个对象,然后呢,通过索引器的语法去给对象添加属性,我前面也介绍过对象的属性,它只能够是字符串或者是eS6所推出的那个symbol,但是呢,由于JavaScript是弱类型的,所以我们可以在索引当中使用任意类型的值作为属性,而在他的内容会自动转换成字符串,比如我们会这个obj去添加true作为属性,那最终的对象,他实际的属性就是字符串的true,也就是说,我们现在使用字符串也可以取到这样的值。有什么问题,如果说我们不知道对象属性名会自动转换成这样一个点,那这里呢,你就可能会感觉很奇怪,那这种奇怪的根源,就是我们用的是一个比较随意的弱类型语言,那如果是强行的话,这个问题也可以彻底避免,在强烈的情况下这里,所以他明确有类型要求,我们不满足类型,要求这样一个成员在语法上就行不通。

那总结下这里的三个例子,第一个例子当中,因为弱类型的关系,我们当中一些类型异常,需要等到运行时才能够发现,而在第二个例子当中因为弱类型关系,他类型不明确,就会造成我们函数功能有可能发生改变,在第三个当中,因为弱类型关系就出现了我们对对象索引器的一种错误的用法,综上,弱类型语言它的弊端是使得明显的,只是在代码量小的情况下,这些问题我们可以通过约定方式去规避,而对于一些开发周期特别长的大规模项目那这种。君子约定的方式仍然会存在隐患,那只有在语法层面的强制要求才能够提供更可靠的保障,所以说呢,强类型语言的代码,在代码可靠程度上是有明显优势的,那使用强类型语言呢,就可以提前消灭一大部分有可能会存在的类型异常,而不必等到我们在运行过程中再去慢慢的一半。

强类型语言的优势

  1. 错误更早的暴露
  2. 代码更智能,编码更准确

强类型语言编辑器能时时刻刻提醒你代码的错误或异常

// 强类型语言的优势
function render (element){
    element.className="container"
    element.innerHtml = '你好'
}
  1. 重构更牢靠
// 重构
const until = {
    aaa:()=>{
        console.log('until')
    }
}
  1. 减少不必要的类型判断
// 类型判断
function sum(a,b){
    // 强类型不需要这种判断
    if(typeof a !=== 'number' || typeof b !=== 'number'){
        throw new TypeError('参数必须是数字')

    }
    return a + b
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vv6Thjee-1597675404563)(E46E31B8F25F4900A682CDF63B704423)]

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值