javascript语言特性

31 阅读7分钟

javascript 语言特性

核心特点

  1. 解释型
  2. 弱类型
  3. 脚本语言
  4. 单线程
  5. 异步与事件循环
  6. 事件驱动和非阻塞I/O
  7. 面向对象(基于原型)
  8. 函数是一等公民

解释型

解释型语言:你可以理解为现炒菜,写好代码->直接运行。(解释器边解释边执行)

优点

  1. 无需显示编译,即时执行
  2. 跨平台(语言本身不具备跨平台的特性,依赖解释器/虚拟机实现)
  3. 灵活性与动态性(可以快速迭代)
  4. 调试方便(不需要重新编译)

缺点

  1. 执行速度相对于编译执行要慢一点(但是绝大多数浏览器的瓶颈不在解释执行,而是在网络上)
  2. 源代码通常需要分发/暴漏(通常是代码混淆、压缩增加阅读难度)

编译型

编译型语言:你可以理解为预制菜。写好代码 -> 编译 -> 运行可执行文件

特点:

  1. 编译器需要全部编译成平台相关的机器码
  2. 运行速度快
  3. 依赖平台
  4. 迭代更新周期长(适合长期稳定)
  5. 编译时可处理完成大多数错误
  6. 不会暴露源码

弱类型(动态类型)

javascript选择弱类型(动态类型)的原因,主要时考虑到解释型特性,快速迭代需求,以及降低门槛的设计哲学紧密相关。

优点

  1. 降低学习门槛(和取名javascript类似,便于快速推广)
  2. 支持快速原型开发(不浪费时间在类型声明和转化上,和HTML语言一脉相承,统一协调)
  3. 适应web的动态特性(用户输入和数据格式可能随时发生变化,需要灵活应对)
  4. 避免中断的机制(try-catch,避免类型错误导致整个崩溃)

缺点

  1. 类型错误出现运行时
  2. 调试困难(难以追踪,需要断点调试)
  3. 性能开销更大
  4. 重构困难,没有运行根本不知道合适何地类型被更换

TypeScript

随着javascript的普及应用。弱类型已经不是那么被需要,而且因为隐式的类型转化造成维护成本的攀升。但是由于历史原因(不能因为版本更新,就对以前的项目进行全盘否定),浏览器支持的底层运行时仍然保持弱类型。

脚本语言

“脚本语言”并非一个严格的技术标准,而是一个基于设计目的和使用方式的归类。其核心特征是:

  1. 控制与粘合:脚本语言通常不是用来“创造”一个全新的独立系统,而是用来控制、协调或“粘合”  其他已经存在的、更复杂的组件或应用程序。
  2. 解释执行:通常是解释型语言,无需独立的编译步骤,由宿主环境的解释器直接读取源代码并执行。
  3. 高层抽象:提供了高级、简洁的语法,专注于要完成的任务逻辑,而非底层细节(如内存管理)。
  4. 快速开发与迭代:语法灵活(常为动态类型),编写简单,修改后能立刻看到结果,非常适合自动化、快速原型和交互式任务。

javascript 设计之初就是为了作为浏览器的控制脚本使用。

  • 他的执行依赖浏览器提供的环境:渲染引擎、网络请求、DOM和BOM。
  • 执行模式:解释执行
  • 核心特点:动态类型以及高层抽象(不会设计内存管理以及线程管理等底层功能)
  • 适合快速迭代。

单线程

原因:

  1. 单线程模型大大降低了入门门槛。
  • 多线程会造成:竞态条件、死锁、线程同步、复杂的调试
  1. 避免DOM操作冲突(出口只有用户界面)
  • 允许多线程同时操作DOM,会出现数据不一致、渲染错乱等问题

但是单线程主要面对的挑战:线程阻塞

解决方案:事件循环+异步回调

现代浏览器:也支持了提供了web Workers多线程的解决方案,但是由于出口只有用户界面,所以多线程方案不支持DOM操作

异步回调与事件循环

异步回调

异步回调是JavaScript处理非阻塞操作的核心机制。

JavaScript是单线程的,意味着只有一个执行栈,不能因为同步任务的执行等待过程,而阻塞线程。

web的等待本质:(通常阻塞javascript线程的不是语言的执行。而是等待其他线程任务的结果)

  • 网络请求
  • 用户输入
  • 定时任务
  • 文件读写

回调函数就是一个被作为参数传递,并在特定条件满足时被调用的函数。

当其他线程任务完成后,通过事件循环机制将回调函数的任务加入到队列中,等待执行栈调用执行。

事件循环(任务排队机制)

事件循环是JavaScript的异步任务调度器,它在执行栈清空后,首先清空所有微任务队列,然后从宏任务队列中取出一个任务执行,如此循环;若所有队列为空,则进入休眠等待新任务到来。

事件驱动和非阻塞I/O

事件驱动是一种编程范式,程序的执行流程由事件(如用户操作、系统消息、网络请求完成等)的发生来驱动,而不是按照预定的顺序执行。

  1. 基于回调函数:事件发生时调用预先注册的回调函数
  2. 异步处理:不阻塞主线程,继续执行后续代码
  3. 事件循环机制:JavaScript 引擎使用事件循环处理事件队列

非阻塞I/O 指的是在进行输入/输出操作时,不会阻塞程序执行线程,而是立即返回,让程序可以继续执行其他任务。

  1. 高并发性能:单线程可以处理大量并发连接
  2. 资源高效:不需要为每个连接创建新线程
  3. 响应性好:主线程不会被阻塞,保持响应性
  4. 适合I/O密集型应用:如Web服务器、API服务

主要问题

  1. CPU密集型任务:会阻塞事件循环
  2. 回调地狱:多层嵌套的回调难以维护
  3. 错误处理复杂:异步错误传播困难

面向对象(基于原型)

我们通常说JavaScript是基于原型的面向对象语言,这与基于类的语言(如Java、C++)不同。在JavaScript中,对象可以直接继承其他对象,而不需要类的概念。

但是,ES6引入了类的语法,但这只是语法糖,底层仍然是基于原型的继承。

主要特性:

  1. 原型链:每个对象都有一个原型对象,对象从原型对象继承属性和方法。
  2. 构造函数:用于创建对象的函数,通常与new操作符一起使用。
  3. 实例:通过构造函数创建的对象称为实例,实例共享构造函数的原型对象上的属性和方法。

函数是一等公民

在编程语言中,一等公民(First-class Citizen)  指的是该语言中的实体(如变量、函数等)具有以下能力:

  1. 可以被赋值给变量
  2. 可以作为参数传递给函数
  3. 可以作为函数的返回值
  4. 可以存储在数据结构中
  5. 具有自己的身份标识(名称)

函数编程的基石

  1. 高阶函数
  2. 柯里化(Currying)
  3. 函数组合(Function Composition)

JavaScript 中"函数是一等公民"这一特性意味着:

  1. 函数拥有最高的灵活性:可以像任何其他值一样被传递和使用
  2. 支持高阶函数:函数可以作为参数和返回值,实现强大的抽象能力
  3. 实现函数式编程范式:支持纯函数、不可变性、函数组合等概念
  4. 创建闭包:函数可以捕获和记住其创建时的上下文
  5. 实现各种设计模式:如工厂模式、策略模式、装饰器模式等

这一特性是 JavaScript 强大表现力的核心,使得它能够:

  • 轻松处理异步操作(回调、Promise、async/await)
  • 实现简洁的事件驱动编程
  • 创建灵活的可复用代码模块
  • 支持现代前端框架(React、Vue、Angular)的函数式组件和 hooks