关于javascript:JavaScript类型系统

54次阅读

共计 3274 个字符,预计需要花费 9 分钟才能阅读完成。

目录

  • 类型零碎

    • 类型平安 —— 强类型 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 自在类型零碎问题的解决方案

这里之后会进行内容补充

  • flow —— JavaScript 动态类型查看器
  • TypeScript —— JavaScript 超集

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

编译型语言

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

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

解释型语言

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

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

正文完
 0