学习面向对象之前,我们都应该了解它的特点:
1.面向过程:
面向过程的思想把一个项目或者一件事情按照顺序一步一步完成。 关注过程,分步执行
2.面向对象(Object Oriented Programming): 面向对象的思想把一个项目或者一件事情,分成更小的项目或者更小的部分,每一个部分负责什么功能,然后在把这些部分组成一个整体。
面向对象的特点
抽象:关注核心,关注重点。
封装:和函数特点吻合(常用的重复的代码进行封装,避免代码冗余)
继承:子类可以继承父类,不能影响父类。
多态:js使用比较少,对象具有多种不同的形态
面向对象的适应场景:
面向对象适合:复杂的场景。
避免全局污染(全局变量全局函数),更方便的扩展程序。
更清楚,更熟悉系统提供的一些默认类和对象的实现-系统提供的类(构造函数)全部采用面向对象实现。
1.面向对象的两种写法
混合开发:构造函数+原型
es新增:class类进行开发
2.两个原型:prototype,proto
每一个函数都有prototype属性
每一个对象都有__proto__,原型链的核心
3.原型链的概念:实例对象(proto)与原型(prototype)之间的连接
4.面向对象oop案例操作
全局变量–属性
全局函数–方法
this指向–箭头函数
将一个项目–更小的项目–整合(局部–整体)–功能单独分离。
1.混合开发
使用的最频繁的就是对函数进行封装,解决代码冗余的问题,而专家将其称为工厂模式。
但是工厂模式是存在弊端的:帮我们解决创建多个对象代码冗余的问题,无法解决识别问题,所有的对象依然由object创建的。不像Array,Date…
解决的办法就是:参考系统类(构造函数),调用的时候前面添加new.
结论:一旦通过new调用函数,当前的函数就不是普通函数,变成了构造函数了(符合构造函数的特点)。
构造函数的两个特点:首字母大写,new调用。
代码实例:
//传统写法:构造函数+原型
function Person1(name) {
this.name = name;
}
Person1.prototype.sayHello = function () {//原型上面的方法,公有的。
console.log(this.name + ':say hello');
}
Person1.prototype.sayHi = function () {//原型上面的方法,公有的。
console.log(this.name + ':say hi');
}
2.ES6新增的class方法:
class:类。面向对象强调的就是类的概念。之前一直说js基于面向对象的,因为那个时候没有类这个概念。
es引入class
JavaScript 语言中,生成实例对象的传统方法是通过构造函数。
ES6 提供了更接近传统语言的写法,引入了 Class(类)这个概念,作为对象的模板。通过class关键字,可以定义类。
ES6 的class可以看作只是一个语法糖,它的绝大部分功能,ES5 都可以做到,新的class写法只是让对象原型的写法更加清晰、更像面向对象编程的语法而已。
语法糖:指计算机语言中添加的某种语法,这种语法对语言的功能并没有影响,但是更方便程序员使用,常来说使用语法糖能够增加程序的可读性,从而减少程序代码出错的机会
class写法实例:
//class写法--多实用class写法,熟悉传统的写法。
class Person {
constructor(name) {//存放属性,等同于上面的构造函数。
this.name = name;
}
//这里constructor和方法之间不能有任何符号。
sayHello() {
console.log(this.name + ':say hello');
}
//这里方法之间不能有任何符号。
sayHi() {
console.log(this.name + ':say hi');
}
}
let p1 = new Person('语法糖');
// console.log(p1.name);
// p1.sayHello()
// p1.sayHi()
console.log(typeof Person1);//function
console.log(typeof Person);//function 语法糖
对面向对象进行总结就是 面向对象的技巧和规律整理:
面向对象开发的第一种方式(混合开发):构造函数(私有属性) + prototype(原型:公有方法)
1.将每一个案例当做一个类(构造函数),利用类(构造函数)下面的对象进行相关的操作(很多公司都是有要求面向对象来写项目,也可以通过此方法更好的学习后面的模块化开发)。
2.案例实现过程中,将之前常见的全局变量改成属性,全局函数变成方法(整体-局部原则)。
3.变量是有作用域的,函数内部的变量外部无法获取,属性是对象下面的,可以在面向对象的开发中随时调用,方便操作。
4.注意this的指向问题(谁调用函数this指向谁,方法也是函数构建的,构造函数里面的this指向new出来的实例对象,也就是实例对象可以任意的访问构造函数下面的属性和方法)--也可以使用箭头函数将this固有化。
5.多改写案例,理解面向对象的意义,不要习惯过去的函数式编程(不利于扩展,维护,影响工作中的应用)
6.理解面向对象的优势:
-面向对象适合复杂的场景。
-避免全局污染(全局变量全局函数),更方便的扩展程序。
-更清楚熟悉系统提供的一些默认类(构造函数)和对象的实现-系统提供的类(构造函数)全部采用面向对象实现。
对于面向对象我们还需要了解一个东西:原型链;
1.原型链
prototype:每一个函数下面都有原型对象prototype(引用类型),里面放置的是实例化对象公有的属性或者方法。内部this指向实例对象的。
//和__proto__:每一个对象都有一个原型(内部原型), 原型链上的对象正是依靠这个属性连结在一起.作为一个对象,当你访问其中的一个属性或方法的时候,如果这个对象中(构造函数)没有这个方法或属性,那么Javascript引擎将会访问这个对象的__proto__属性所指向上一个对象,并在那个对象中查找指定的方法或属性,如果不能找到,那就会继续通过那个对象的__proto__属性指向的对象进行向上查找,直到这个链表结束。
简要的理解可以如下图一般