我看JavaScript(一)

javascript或JS是什么?这个问题对于有编程经验的人,或者有JS经验的人都是显而易见的,但是,却未必都深刻和全面。此文记录一下我目前对JS的一些认识。

应该说,JS是一种与互联网Web技术发展相伴相生的一种编程语言,从最开始“胶水”脚本语言,为表单提交进行数据验证功能,到现在支持开发单页应用(single page web application,SPA),完全面向对象式的编程,JS发展了很多高级的特性,这些特性如此之多,以至于给人的感觉JS,比较传统JAVA,C还要复杂的一种语言。

JS核心特性

JS编程的内容很“大”,我读过一些经典的书籍,包括犀牛书、小孩观天象的红皮书和孔雀鸟书,我觉得这三本介绍JS比较全面,而其中犀牛书行文和内容组织最佳,至少非常适合我这种偏抽象思维的学习者。犀牛书算偏理论类的书,也有1000页的内容,可见JS之大。

Screenshot from 2019 01 22 11 50 28

JS编程真的很大,初学者学习它我个人认为可以分两个部分,第一是JS核心特性;第二是在核心上构建的各种库和计算环境特性,例如BOM,DOM等(软件工程管理、编译构建、版本跟踪等属于JS编程之外的内容)。本文就JS核心特性作一个概略性介绍,和引申一下JS核心与核心之外之间的关系。

JS核心特性应该是学习JS编程的基本功,比较抽象,很费功夫,但很重要。JS核心特性包括以下一些关键字:

  • 高级语言
  • 命令式
  • 结构化
  • 弱类型
  • 动态性(函数与对象动态、异步计算)
  • 继承复用(原型机制)
  • 高阶函数表达
  • 标准库JOM

以上是我认为一些JS关键特性,而像匿名函数、字面量对象、函数即时调用、闭包和函数是“一等公民”等这些“常见特性”其实是JS核心特性的具体表现。

核心之外的特性:

  • BOM
  • DOM
  • 第三方库(例如jQuery)

核心特性的前三个是JS作为高级语言的通用属性,而动态性、继承和高阶函数才是JS作为一种编程语言重要的核心特性。

高级语言

这是一切现代型编程语言的通性。“高级”是相对于使用机器符号指令进行编程的“低级”机器语言而言。你可以使自然语言符号来「表达计算算法」,包括数据(变量)和计算指令(语句)。作为使用高级编程语言的程序开发者,他的工作就是使用语言提供的高级操作指令和数据,编写出算法程序指导一台高级的机器执行任务(例如JS对应的JS机),语言是人机之间的(表达和交流的)语义媒介。注意语言机与编译器是两回事,语言机是执行高级语言程序的抽象机器,编译器只是负责将高级语言转译低级的物理机器指令。同样,编程理论和编译理论也是两回事,编程理论是指导程序员如何编写程序,编译理论是指导编译器开发者编写编译器。我在这里讲的主要也是编程理论(中语言中特性)。

注:JS社区中,有“变量提升、闭包是函数和声明该函数的词法环境的组合”这样的提法,说明了,编程与编译界限不清很流行

与编程理论相关的重要概念有:

  • 数据(类型及其值)及其操作、变量、表达式、语句、函数、类对象
  • 语法语义
  • 编译、解释

命令式

命令式特性是指程序是由一条条指导机器执行计算的指令组成,机器执行这些指令来改变程序状态来完成计算目标,所谓产生side effect。相对于命令式编程的是声明式编程,通过描述计算结果来达到完成计算任务的一种编程范型,CSS就是典型的声明式编程。命令式特性决定「JS语句」是由完整赋值操作和操作数据组成,对变量(新变量)或对象属性产生side effect,如果只有数据,那只是个表达式。

结构化

这里的结构不是数据对象的结构,而是指令执行「次序结构」,一种时间结构。简单的计算任务指令执行次序是线性的,而当计算任务变得复杂后,执行次序是非线性的,会跳来跳去。最初应对非线性的编程机制是GOTO语句。当GOTO被认识到有害后,就产生了多种结构式流程控制特性。事实上,这些次序结构本身是计算任务本身的结构特性决定的。编程的流程结构包括分支(顺序、选择、循环和递归)、子程序和代码块。

Structured program patterns 1

弱类型

(完成计算任务的)值有多少种类型,这些类型有怎样的处理属性,决定了语言形式特性。例如JS的弱类型系统。JS的弱类型的意思是比较易懂的:

The process of verifying and enforcing the constraints of types—type checking—may occur either at compile-time (a static check) or at run-time. If a language specification requires its typing rules strongly (i.e., more or less allowing only those automatic type conversions that do not lose information), one can refer to the process as strongly typed, if not, as weakly typed.

验证和强制类型检查约束的过程可以在编译时(静态检查)或运行时发生。如果一种语言规范强制要求它的类型规则(例如:,或多或少地只允许那些不丢失信息的自动类型转换),您可以将该语言称为强类型,反之,则称为弱类型。

但是为什么如此设计则要多一些思考(也就是设计的意义)。

JS的弱类型的一种直显意义是隐式类型转换(看下图),计算机处理是数值,而人读是字符,在人机交互的情景,需要类型转换。类型系统设计初衷之一是安全性,这个安全性是指程序行为正确性,这也很适合常理,什么样数据类型就做什么样的处理。但是,为什么JS放弃这种安全性,变量只一个数据容器,爱装啥就啥?

JS

什么叫类型和类型系统?

当我们说variableA是数值类型时:值对人的涵义(数值)、值范围(64位)以及处理(算术运算) 类型(及其意义):值的可能范围,以及值的可能处理方式 某种计算行为上的约束规则

其实变量数据有类型只是编程语言「类型系统」的一部分,计算机程序的各种构件(变量、表达、函数或模块)都有“类型”属性。

类型系统(语言编译器解释器支持):类型(各种)、类型转换、类型检查(typeof) 类型:程序员的理解与机器的实现

我们可以拿JS和强类型语言比较,和顺着互联网应用的历史的发展来大概推断出JS类型系统设计原因。

弱类型优点

JS引入弱类型或许一开始是一个历史的选择,胶水语言嘛简单点好,后来才有了正式的发展。

  • 如果编程足够的安全,计算应用不需太确精细的数据控制,类型错误频率较低,或程序员足够的聪明等,那么是不用强类型;
  • 弱类型(类型少,运行时才由解释器自动检测)可以简化编程coding,因为不需额外的类型信息指导编译器进行类型检查,程序表达更简洁,更容易入门。

强类型优点

由于编译前就知道计算的类型信息,所以强类型语言用最优的方式组织程序物理结构,从而达到优化编译结果。这是强类型的优势。

语言类型系统的类型约束越多,程序就越安全,但是越难写(程序员烧脑),相反类型变弱(类型检查交给运行时解释器)程序就变得较好写。所以,语言的类型有多强多弱,是程序复杂性、安全性、编写性、编译器实现等多方面的设计的结果。

对语言类型系统的认识有助更好理解和应用JS的API:

var let const 'use strict' null undefined typeof

裸男
Nakeman.cn 2023 Build by Gatsby and Tailwind, Deploy on Netlify.