背景
在团队的每日分享中,有java同事说到,js是面向过程的,不像java一样,它不是面向对象语言
js 支持面向对象编程吗?
个人认为,支持!
理由如下:
1、面向对象只是一种概念或者说是编程思想,它不依赖于哪一种语言而生。
2、js都不是面向对象语言,没有class,如何面向对象?
- 在ES6中,class (类)作为对象的模板被引入,可以通过 class 关键字定义类。class 的本质是 function。它可以看作一个语法糖,让对象原型的写法更加清晰、更像面向对象编程的语法
那ES6之前不就没有吗?
- 不支持ES6语法的浏览器,需要编译成ES5,说明class语法能被编译成最原始的实现方式
- 如果说vue等框架才能支持面向对象,那vue编写的代码也不是直接被浏览器识别的,最终编译成了什么呢,都说明了---js 可以支持面向对象编程
3、
- 面向过程就是亲力亲为,事无巨细,面面俱到,步步紧跟,有条不紊
- 面向对象就是找一个对象,指挥得结果
面向对象的设计思想是:
- 抽象出 Class(构造函数)
- 根据 Class(构造函数) 创建 Instance
- 指挥 Instance 得结果
- 面向对象的抽象程度又比函数要高,因为一个 Class 既包含数据,又包含操作数据的方法。
js如何实现面向对象?
Javascript是一种基于对象的语言,你遇到的所有东西几乎都是对象。但是,它又不是一种真正的面向对象编程(OOP)语言,因为它的语法中没有class(类) 。那么,如果我们要把"属性"(property)和"方法"(method),封装成一个对象,甚至要从原型对象生成一个实例对象,我们应该怎么做呢?---- “构造函数”
function Dog(name){
this.name = name;
this.species = '犬科';
}
var dogA = new Dog('大毛');
var dogB = new Dog('二毛');
console.log(dogA.name,dogB.name);//大毛,二毛
但是构造函数有个问题,浪费内存,怎么理解呢?
每一个实例对象,都有自己的属性和方法的副本。这不仅无法做到数据共享,也是极大的资源浪费
dogA.species = '猫科';
console.log(dogA.species,dogB.species);//猫科,犬科,互不影响
prototype属性的引入
Javascript规定,每一个构造函数都有一个prototype属性,指向另一个对象。这个对象的所有属性和方法,都会被构造函数的实例继承。
这意味着,我们可以把那些不变的属性和方法,直接定义在prototype对象上。
function DOG(name){
this.name = name;
}
DOG.prototype = { species : '犬科' };
var dogA = new DOG('大毛');
var dogB = new DOG('二毛');
console.log(dogA.species,dogB.species); // 犬科,犬科
dogA.species = '猫科';
console.log(dogA.species,dogB.species); //猫科,犬科
这同时也是 Javascript继承机制的设计思想
附:下面是一个放烟花的例子的部分代码,将面向过程的写法改成了面向对象