JS中面向对象的理解

209 阅读3分钟

背景

在团队的每日分享中,有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继承机制的设计思想

附:下面是一个放烟花的例子的部分代码,将面向过程的写法改成了面向对象