JavaScript类型系统

目录

  • 类型系统
    • 类型安全 —— 强类型 VS. 弱类型
      • 两者之间的区别
    • 类型检查 —— 静态类型 VS. 动态类型
      • 两者之间的区别
  • JavaScript类型系统的特征
  • 为什么JS是弱类型且动态类型呢?
    • 为什么需要类型检查呢?
    • 弱类型的不足
    • 强类型的优势
  • JavaScript自有类型系统问题的解决方案
  • 关于查资料对于编译型语言和解释型语言的知识点补充
    • 编译型语言
    • 解释型语言

这篇文章要先讨论一些概念,这些概念我们在开始学习JavaScript的时候就知道了,JavaScript是一个弱类型且动态类型的语言,那么这些概念具体这里做了整理。之后还要重点讨论的是 JavaScript自有类型系统的问题,以及如何借助一些优秀的技术方案,解决这些问题。

类型系统

我们经常用两个维度去描述一个编程语言的特性,这两个维度不要混淆,强类型并不是动态类型...

  • 强类型与弱类型,这是从类型安全的维度分类
  • 静态类型与动态类型,这是从类型检查的维度分类

类型安全 —— 强类型 VS. 弱类型

强类型 :要求语言层面限制函数的实参类型必须与形参类型相同。

弱类型 : 语言层面不会限制实参的类型。

下面举个例子:

// Java
class Main {
    // 这里定义了传入的参数是int类型,那么实际的时候也应该是int类型
    static void foo(int num) {
        System.out.printIn(num);
    }
    
    public static void main(Sting[] args) {
        // 下面的如果int类型就通过,如果不是int类型就会报错
        Main.foo(100); // ok
        Main.foo('100'); // error "100" is a string
        Main.foo(Integer.parseInt("100")); // ok
    }
}
// ---------------------------------------------------
// JavaScript
// 传的时候没有规定是什么类型,那么实参是什么类型都不会报错
function foo(num) {
    console.log(num)
}

foo(100) // ok
foo('100') // ok
foo(parseInt('100')) // ok

由于这种强弱类型之分根本不是某一个权威机构的定义,所以之后的人们对制定的细节出现了不一样的理解。大致也就是说强类型有更强的类型约束,而弱类型中几乎没有什么约束。

两者之间的区别

强类型语言中不允许有任何的隐式类型转换,而弱类型语言则允许任意的数据隐式类型转换。

// JavaScript
// js报的错误都是在代码层面,运行的时候通过逻辑判断手动抛出的,并不是语法层面的类型限制
// 下面'100'是字符串,在做减法的时候进行了隐式类型转换,转换成了Number类型,最后得到的结果是50,Number类型。
> '100' - 50
50
// 下面字符串进行隐式类型转换,不是数字的成为NaN(不是数字)
> Math.floor('foo')
NaN
// 布尔值进行隐式类型转换,转成了数字1
> Math.floor(true)
1
# python
# 这里无法进行隐式类型转换,会在语法层面上报类型错误
> '100' - 50
TypeError: unsupported operand type(s) for -: 'str' and 'int'
> abs('foo')
TypeError: bad operand type for abs(): 'str'

类型检查 —— 静态类型 VS. 动态类型

都比较统一,没什么争议

静态类型 :一个变量声明时它的类型就是明确的,声明过后,类型不能修改。

动态类型 :运行阶段才可以明确变量的类型,而且变量的类型随时可以改变。所以动态类型语言中的变量没有类型,变量中存放的值时有类型的。

// Java
class Main {
    public static void main(String[] args) {
        // 一开始就定了num的类型是int,如果修改也只能修改成int类型,如果修改成string就会报错
        int num = 100;
        num = 50; // ok
        num = '100' // error
        System.out.printInt(num);
    }
}

// JavaScript
// 可以随意修改num的类型
var num = 100
num = 50 // ok
num = '100' // ok
num = true // ok
console.log(num)

两者之间的区别

静态类型不能修改变量的类型,动态类型可以随时去修改变量的类型。

JavaScript类型系统的特征

JavaScript是弱类型且动态类型的语言,灵活多变,可以进行 隐式转换 ,也可以进行 类型推断 ,但是缺失了类型系统的可靠性。

为什么JS是弱类型且动态类型呢?

  • 早前的JavaScript应用简单,所以并没有复杂的类型系统
  • JavaScript是脚本语言,没有编译环节,所以设计成静态语言是没有意义的

为什么需要类型检查呢?

  • 因为现在的JavaScript应用越来越复杂,开发周期也越来越长,越来越大的项目几百行代码已经不满足现状了,所以现在弱类型已经成为了JavaScript的短板。
  • 这些东西只能通过约定去规避问题,但是在大型项目中通过人为约定存在隐患。

弱类型的不足

  1. 只有在运行阶段才能发现代码的异常,代码没有执行的时候也无法发现代码异常,在隐藏比较深的情况下,测试不能百分百覆盖。
const obj = {}
obj.foo()  // TypeError: obj.foo is not a function

// 下面这个延时器,在时间到了之后才会运行,给测试带来麻烦
setTimeout(() => {
    obj.foo()
}, 100000)
  1. 函数参数类型不确定,输入的结果有偏差
// 不明确是数字,所以结果不一样
function sum (a, b) {
    return a + b
}

console.log(sum(100, 100)) // 200
console.log(sum(100, '100')) // 100100
  1. 隐式类型转换在对象属性名转化成字符串,里面的内容会有很多的问题
// 定义一个字符串,对象的属性名不能是对象,会自动转换成字符串,如果不满足就会有问题
const obj = {}
obj[true] = 100
obj[{name:1}] = 1
console.log(obj) // {true: 100, [object Object]: 1}
console.log(obj['true']) // 100
console.log(obj["[object Object]"]) // 1

强类型的优势

  1. 错误在开发阶段就会暴露,越早发现越好
  2. 代码更智能,编码更准确(开发工具的智能提示因为有变量类型才有提示)
  3. 重构更牢靠(如果项目中很多地方用到的成员,需要删除成员或者修改成员名称的时候,弱类型语言会有隐患)
  4. 减少不必要的类型判断
function sum (a, b) {
    if (typeof a !== 'number' || typeof b !== 'number') {
        throw new TypeError('arguments must be a number')
    }
    return a + b
}

JavaScript自由类型系统问题的解决方案

这里之后会进行内容补充

关于查资料对于编译型语言和解释型语言的知识点补充

编译型语言

使用专门的编译器,针对特定的平台,将高级语言源代码一次性的编译成可被该平台硬件执行的机器码,并包装成该平台所能识别的可执行性程序的格式。

编译型语言一次性的编译成平台相关的机器语言 文件,运行时脱离开发环境,与特定平台相关,一般无法移植到其他平台,现有的C、C++、Objective等都属于编译型语言。

解释型语言

使用专门的解释器对源程序逐行解释成特定平台的机器码并立即执行。是 代码在执行时才被解释器一行行动态翻译成机器语言和执行,而不是在执行之前就完成翻译。

解释型语言每次运行都需要将源代码解释称机器码并执行,只要平台提供相应的解释器,就可以运行源代码,Python、Java、JavaScript等属于解释型语言。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,997评论 6 502
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,603评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 163,359评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,309评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,346评论 6 390
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,258评论 1 300
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,122评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,970评论 0 275
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,403评论 1 313
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,596评论 3 334
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,769评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,464评论 5 344
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,075评论 3 327
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,705评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,848评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,831评论 2 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,678评论 2 354

推荐阅读更多精彩内容