You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
其实,现在已经不适合用解释型和编译型来区分一门语言了,不能说一种语言只能是解释或者只能是编译。比如 C 语言可以说是编译型语言,编译生成的目标文件(机器码)是针对特定 CPU 的。而 Java 虽然是非编译型的,却也有某种编译过程,它们编译生成的通常是平台无关的中间代码(字节码,*.class文件),而虚拟机( Java 虚拟机,JVM)在运行过程中将中间代码翻译成目标平台 (不同 CPU 平台) 的指令。
Value Class Type
-------------------------------------
"foo" String string
new String("foo") String object
1.2 Number number
new Number(1.2) Number object
true Boolean boolean
new Boolean(true) Boolean object
[1,2,3] Array object
new Array(1, 2, 3) Array object
new Function("") Function function
/abc/g RegExp object (function in Nitro/V8)
new RegExp("meow") RegExp object (function in Nitro/V8)
{} Object object
new Object() Object object
JavaScript 是一种动态的,基于原型和多范式的脚本语言,支持面向过程,面向对象和函数式编程,命令式和声明式的编程风格。比如 C 风格的过程式编程,包括大括号和复杂的 for 语句,以及不太明显的 Scheme/Lisp 风格的函数式编程。
JavaScript 是简单直接的,你不需要对编程有很多的了解就可以用它来完成工作。事实上,每个人的电脑里都安装了一个 JavaScript 解释器,只需要打开你的浏览器,在控制台输上一段
alert('hello world!')
,你就已经在编写 JavaScript 了。JavaScript 也是一门重要的语言,它与浏览器结合在一起,我们无时无刻不在享受 JavaScript 的魔力,从这里也能获知,JavaScript 是 GitHub 上最为流行的语言。
解释型与编译型
其实,现在已经不适合用解释型和编译型来区分一门语言了,不能说一种语言只能是解释或者只能是编译。比如 C 语言可以说是编译型语言,编译生成的目标文件(机器码)是针对特定 CPU 的。而 Java 虽然是非编译型的,却也有某种编译过程,它们编译生成的通常是平台无关的中间代码(字节码,*.class文件),而虚拟机( Java 虚拟机,JVM)在运行过程中将中间代码翻译成目标平台 (不同 CPU 平台) 的指令。
尽管 JavaScript 通常被认为是一门解释执行的语言,但事实上它也有编译。传统的 JavaScript 引擎是把 JavaScript 代码先编译为字节码,然后再通过解释器执行字节码。而新一代的 JavaScript 引擎为了提高性能,引入了 Java 虚拟机和 C++ 编译器中的众多技术,比如 V8 是运用 JIT (Just-in-time,即时编译) 技术,不通过解释器执行,而且直接编译成运行在 CPU 上的机器码,不过,就在几个月前, V8 新增了一个 Ignition 字节码解释器 ,将默认启动。具体可参考 V8 Ignition:JS 引擎与字节码的不解之缘 。
JavaScript 的优势
对象字面量
JavaScript 有非常强大的对象字面量表示法。通过列出对象的组成部分,就能创建对象。这种表示法也是 JSON 的灵感来源。
函数
函数可能是 JavaScript 中设计最出色的部分。函数是一等公民,这意味着可以把函数像其它值一样传递。 一个常见的用法是把匿名函数作为回调函数传递到异步函数中。
函数声明和函数表达式
闭包
闭包的本质源自两点,词法作用域和函数当作值传递,一个函数被当作值返回时,也就相当于返回了一个通道,这个通道可以访问这个函数词法作用域中的变量。我们可以通过闭包模拟私用变量的特性,也可以用来实现柯里化,一种多参数函数的方法。
高阶函数
高阶函数是指接受或者返回一个函数的函数。因为在 JavaScript 中函数是一等公民,所以高阶函数非常容易实现。比如原生的
Array.map
,Array.filter
等方法。函数当做值传递,柯里化,高阶函数等都是 JavaScript 函数式编程的体现。函数重载与重写
JavaScript 不能像其他语言 (如 Java) 一样,可以为一个函数编写两个定义,只要这两个定义的签名 (接受参数的类型和数量) 不同即可。得益于动态弱类型的特性,JavaScript 可以通过检查传入函数中参数的类型和数量,作出不同的反应,来模仿函数的重载。
另外,函数重写是被 JavaScript 原生支持的,对实例对象重写函数也不会影响原型链中的函数。
原型
原型 (prototype) 继承是一个有争议的特性,JavaScript 是唯一一个被广泛使用的基于原型继承的语言,如果你尝试对 JavaScript 使用类的设计模式,将会遇到困难。比如抽象类和接口。
在 Java 等面向类的语言中,使用抽象类也被称为继承,是一种强耦合设计,用来描述 is-a 关系,是对一种事物的抽象。而接口通常用来描述对象所共有的行为,是对行为的抽象,是一种 has-a 关系,可以用来实现组合。
接口和抽象类主要有两点作用:
而 JavaScript 是弱类型的,弱类型意味着不需要利用抽象类或者接口对对象做向上转型,对象继承关系也无关紧要。除了基本数据类型外的其他对象都可以天生地被向上转型成 Object 类型。可以说,JavaScript的多态性是与生俱来的。
在动态类型语言的面向对象设计中,鸭子类型的概念至关重要,利用鸭子类型的思想,我们不需要借助父类就能实现面向接口编程。例如,如果一个对象有
length
属性,可以通过下标存取属性,那么就能当做数组来使用,在Object.prototype.toString.call([]) === '[object Array]'
被发现之前,我们经常用下面的方式来判断对象是否是一个数组面向对象 (OOP) 其实是对事物本质的抽象,而 JavaScript 实现这种抽象的方法叫原型。
初始值
赋值后
可以看出,当查找一个对象的属性时,JavaScript 会向上遍历原型链,直到找到给定名称的属性为止。而对象的属性是无法修改其原型链中的同名属性,只会自身创建一个同名的属性并为其赋值。
原型继承的一个最大特性就是灵活,因为原型链上的每一个对象及原型链本身都是可以动态修改的。而类继承需要先定义好类和类之间的继承关系,而很难在运行时动态修改这些已经定义好的东西。
动态性
动态弱类型特性,动态混入,鸭子类型,动态修改原型或原型链,甚至修改原生对象的原型,这些特性都是 JavaScript 丰富表现力的源泉。Java 的一些设计模式虽然保证了代码的稳定性,但有时也禁锢了代码的灵活性。
JavaScript 的缺陷
全局变量
全局变量是在所有作用域中都可见的变量,会使得程序难以管理,不过我们也有缓解这个问题的办法,比如创建一个唯一的全局变量作为你应用的容器,或者使用闭包(内部函数总是可以访问其所在的外部函数中声明的参数和变量)来进行信息隐藏。
作用域
大多数语言都拥有块级作用域,在代码块内定义的变量在代码块外是不可见的。可喜的是,ES6新增了
let
关键字,它的用法类似于var
,但是所声明的变量,只在let
命令所在的代码块内有效。typeof
typeof
的返回值几乎都是错误的,我们几乎不可能得到正确的结果。NaN
==
JavaScript 是弱类型语言,这就意味着,
==
操作符会为了比较两个值而进行强制类型转换,而===
操作符不会。参考资料:
JavaScript高级程序设计
JavaScript语言精粹
你不知道的JavaScript
JavaScript设计模式与开发实践
JavaScript 秘密花园
MDN
程序的编译与解释有什么区别?
V8 引擎本用了什么编译技术,使得用 Javascript 与用 C 写出来的代码性能相差无几?
The text was updated successfully, but these errors were encountered: