javaScript是不是面向对象语言?
JavaScript(es6之前)有对象的概念,却没有类的概念,JavaScript对象可以任意添加属性,而java、c++等其他语言却不能。以至于有些人认为JavaScript并非是面向对象的语言,而是基于对象的语言。
实际上JavaScript无疑是面向对象的语言,只不多例如java、c++等语言才用的是“类”的方式来描述对象,这也是最为成功的描述对象方式。但是javaScript采用的较为冷的原型来描述对象的方式。但是由于某些原因JavaScript在原型运行时的基础上加入了例如new、this等语言特性使其看起来更像java。
基于原型的面向对象
“基于类”的编程提倡使用一个关注分类和类之间关系开发模型。在这类语言中,总是先有类,再从类去实例化一个对象。类与类之间又可能会形成继承、组合等关系。类又往往与语言的类型系统整合,形成一定编译时的能力。
“基于原型”的编程看起来更为提倡程序员去关注一系列对象实例的行为,而后才去关心如何将这些对象,划分到最近的使用方式相似的原型对象,而不是将它们分成类。基于原型的面向对象系统通过“复制”的方式来创建新对象。一些语言的实现中,还允许复制一个空对象。这实际上就是创建一个全新的对象。JavaScript的原型对象实现方式并不是真的去复制一个对象,而是使新对象持有一个原型对象的引用。
JavaScript的原型系统其实概括起来如下:
- 如果所有对象都有私有字段 [[prototype]],就是对象的原型;
- 读一个属性,如果对象本身没有,则会继续访问对象的原型,直到原型为空或者找到为止。
这个模型在 ES 的各个历史版本中并没有很大改变,但从 ES6 以来,JavaScript 提供了一系列内置函数,以便更为直接地访问操纵原型。三个方法分别为:
- Object.create 根据指定的原型创建新对象,原型可以是 null;
- Object.getPrototypeOf 获得一个对象的原型;
- Object.setPrototypeOf 设置一个对象的原型。
基于类的面向对象
在es6的新语法中引入了class关键字,并从标准中删除了所有与[[class]]相关的私有属性,new与function的怪异搭配终于可以退休了。基于类的面向对象正式成为JavaScript官方的编程范式。(JavaScript中基于类的面向对象编程实际上是基于原型面向对象编程的语法糖)
class Animal {
constructor(name) {
this.name = name;
}
speak() {
console.log(this.name + ' makes a noise.');
}
}
class Dog extends Animal {
constructor(name) {
super(name); // call the super class constructor and pass in the name parameter
}
speak() {
console.log(this.name + ' barks.');
}
}
let d = new Dog('Mitzie');
d.speak(); // Mitzie barks.