JavaScript为什么叫“JavaScript”?

要回答这个问题还得从JavaScript的历史说起。

1995年5月,Netscape创建了称为Mocha(摩卡)的浏览器端的脚本语言。

可是没过多久,同年9月就改名为“LiveScript”。

又过了没多久,同年12月,Netscape与sun公司合作,将其改名成“JavaScript”了,意为像Java一样的Script(脚本语言)。

为什么最终确定了“JavaScript”这个名字?

“JavaScript”和“Java”到底有多少相似度呢?

我们通过几段代码来简单地比较一下~

既然是“像Java一样”,那么就以Java为准进行对比。而Java作为一门纯正的面向对象的语言(一切皆为对象类),我们就从Java面向对象的3个特性出发进行对比。

封装

封装作为首要特性,指的是能将对象的属性或函数隐藏或暴露出来。

我们创建一个 Animal 对象,让其有个私有属性 name ,同时只能通过对象上的 set/get 方法修改/获取 name 值。

具体代码如下:

// Javaclass Animal { private String name; public void set(String name) { this.name=name;

} public String get() { return this.name;

}

}public class Test { public static void main(String[] args) {

Animal animal=new Animal();

animal.set("dog");

System.out.println(animal.get()); // "dog"

}

}// JavaScript(ECMAScript5) function Animal() { var name=''

this.set=function(a) {

name=a

} this.get=function() { return name

}

}var animal=new Animal()

animal.set('dog')console.log(animal.get()) // 'dog'

对于“封装”特性,两者都能实现,但实现方式还是有些区别。

Java中的类即是对象,用关键字 private 和 public 即可达到封装的效果。

JavaScript中的作用域为函数,所以需要函数来实现。

继承

Java中的继承特性可以让子类获得父类中定义的属性和方法。

class Dog extends Animal {

public String bark() { return "wang wang wang!!!";

}

}

public class Test {

public static void main(String[] args) { Dog dog=new Dog();

dog.set("dog"); System.out.println(dog.get()); // "dog"

System.out.println(dog.bark()); // "wang wang wang!!!"

}

}

JavaScript中实现继承得依赖函数中的prototype属性,将prototype属性指向父类的实例。

function Dog() { this.bark=function() { return 'wang wang wang!!!'

}

}

Dogtotype=new Animal()var dog=new Dog()

dog.set('dog')

dog.get() // 'dog'dog.bark() // 'wang wang wang!!!'

在继承上,JavaScript和Java相比,出现了一些差异:需要在函数声明之后,让其prototype属性指向父类实例以实现继承的效果,继承多个父类时还需要将多个实例进行合并。代码的可维护性和可读性方面,显然不Java如在类的声明时进行定义。

多态

多态我们以函数为例,当一个函数需要对不同的输入结果进行不同的操作时,一般会使用函数重载。下面的例子我们编写一个 bark 的方法,来针对不同的输入进行显示。

class Cat { // 当输入字符串时,直接显示

public String bark(String sound) { return sound;

} // 当为输入时,输出默认值

public String bark() { return "...";

}

}public class Test { public static void main(String[] args) {

Cat cat=new Cat();

System.out.println(cat.bark()); // "..."

System.out.println(cat.bark("miao~")); // "miao~"

}

}

而JavaScript则比较“悲催”,语言本身不支持重载函数,如果多次定义函数则会被覆盖,所以只能通过判断入参来实现多态。

function Cat() { this.bark=function(sound) { if(undefined !==sound && null !==sound) { return sound

} else { return '...'

}

}

}var cat=new Cat()console.log(cat.bark()) //'...'console.logcat.bark('miao')) // 'miao'

在多态这个特性上,JavaScript和Java的区别进一步被放大,因为JavaScript既没有变量类型声明,函数也不支持重载。

更多

JavaScript和Java的语言差异当然可以列出更多,比如最受人诟病之一的便是JavaScript是弱类型语言,这使得代码的健壮性下降:函数可能传入任何可能引起错误的值,但是却只能在执行时发现。当然更高级的接口功能JavaScript原生也是不支持的。

从上面的代码分析可以看出,JavaScript和Java还存在着不小的差异,令人欣慰的时ES6版本对JavaScript有不小的提升,让其更高效和健壮。更令人赞叹的是Typescript这种胶水语言的出现,让代码成为更接近Java的Script。

我们用Typescript把上面3个类重写一下:

// 封装class Animal { private name:string; public set(name:string):void { this.name=name

} public get():string { return this.name

}

}// 继承class Dog extends Animal { public bark():string { return 'wang wang wang!!!'

}

}// 多态class Cat { public call():string

public call(sound:string):string

public call(sound?:string):string { if(undefined !==sound && null !==sound) { return sound

} else { return '...'

}

}

}

和Java语言相比,在 封装 和 继承 特性上写法非常相似,有一些小小的差异比如大小写,类型申明的前后位置,而在 多态 特性上,Typescript增加了类型声明,但是受限于JavaScript语言限制,只能有一个函数实现,仍然避免不了参数判断。

总结

如果说ES6让JavaScript更像python,那么Typescript作为ES6的超集,让JavaScript实至名归——变得更像Java。

这样的好处一方面是让开发者能写出健壮、高效的代码,另一方面是使得JavaSript越来越有可能变成运行在Node.js上的后端语言。对于前端开发者,还是对于JavaScript的全栈开发者来说,都是意义重大的。