语言特点
JavaScript 是一门多范式语言,开发者可以使用过程式风格、面向对象风格以及函数式风格来组织源代码。这一特点使得 JavaScript 能够被不同背景的开发人员所接受。在语言设计上,JavaScript 可谓集众家之所长:
Douglas Crockford 认为,“JavaScript 是第一个成为主流的 Lambda 语言。相对于 Java 而言,JavaScript 与 Lisp 和 Scheme 有更多的共同点。它是披着 C 外衣的 Lisp”[1]。其在语言设计上的优越性,使得 JavaScript 在今天愈加强大。
弱类型
JavaScript 是一门弱类型,或者“动态类型”的语言,并不意味着 JavaScript 语言是“没有类型”的,而是指用户声明标识符(变量)时不必指定类型,且标识符指向的值的类型可以随意更改,即变量的类型通常在运行时确定。
var a = 'some string'; // 初始化时指定 a 为字符串类型
a = {id: 1}; // 但之后也可以让 a 指向一个对象,成为一个引用类型
面向对象
基于原型,JavaScript 支持面向对象的程序设计模式。
// 封装
function Person(name = '', age = null) {
this.name = name;
this.age = age;
}
Person.prototype.sayHello = function() {
var str = `Hi, I am ${this.name}.`;
if (this.age || this.age === 0) {
str += ` I'm ${this.age} years old.`;
}
console.log(str);
}
var wang = new Person('Wang', 29);
wang.sayHello();
// 继承
function Student() {
Person.apply(this, Array.prototype.slice.call(arguments));
}
Student.prototype = new Person();
var st = new Student('XiaoMing');
st.sayHello(); // 调用父类定义给实例的方法
此外,利用每个函数内部的 arguments
上下文变量对实参进行数量与类型的检查,可以实现函数的重载。
函数式风格
JavaScript 里的函数是“一等公民”,即函数本身亦是对象,一个函数可作为另一个函数的返回值,也可以作为其他函数的传入参数。由于 JavaScript 在设计出来时就借鉴了函数式编程语言 Scheme,因此对函数式风格的编程支持得很好。
var arr = [1, 2, 3, 4];
// 内置的函数式编程风格的API
var b = arr.map(item => item * item);
可以用常见的科里化(curring)做到一些很酷的事情:
function multi(x = 1) {
function m(y = 1) {
x = x * y;
return m;
}
m.toString = function() {
return '' + x;
};
m.valueOf = function() {
return x;
}
return m;
}
console.log(multi(2)); // => 1
console.log(multi(2)(4)); // => 8
console.log(multi(1)(2)(3)); // => 6
此外,ECMAScript6 开始列入标准的箭头函数(Arrow-Functions)可以轻松地实现 λ 表达式(Lambda Expressions)风格的代码:
var y = x => x * x;
var val = y(2); // val 的值为 4
参考资料
- Douglas Crockford. JavaScript 语言精粹[M]. 北京: 电子工业出版社, 2012.