文章目录
- 两大编程思想
- ES6中的类和对象
两大编程思想
面向过程 (Procedural-Oriented Programming,POP)
- 定义:面向过程的编程是一种基于过程调用的编程范式,它将程序看作是一系列函数或过程的集合。每个函数负责完成特定的任务
- 特点
- 顺序执行:程序按照先设定好的顺序执行一系列步骤
- 数据和功能分离:数据结构和处理数据的函数通常是分开的
- 重用性:通过函数的形式提高代码的复用性
- 模块化:可以将大型程序划分为多个小的模块或函数来简化开发
- 适用场景:适合于小型到中型项目,尤其是那些逻辑相对简单、不需要复杂的数据结构管理的应用
面向对象 (Object-Oriented Programming,OOP)
- 定义:面向对象编程是一种编程范式,它使用“对象”——数据和操作这些数据的方法的封装体——来设计应用程序和计算机程序。OOP的核心概念包括类、对象、继承、封装、多态等
- 特点
- 封装性:将数据(属性)和行为(方法)绑定在一起,形成一个独立的单元(即对象),并且可以限制外部直接访问对象内部的状态
- 继承性:允许创建一个新类,该类继承另一个已存在的类的属性和方法,从而促进代码复用
- 多态性:同一个行为可以有不同的实现方式(多态性),这使得不同类的对象可以通过相同的接口以不同的方式实现相同的行为
- 抽象:通过抽象类和接口,可以隐藏复杂的实现细节,只暴露必要的信息给用户
- 适用场景:适用于大型项目,特别是需要处理复杂数据相关和业务逻辑的情况。面向对象编程有助于更好的组织代码,提高可维护性和扩展性
ES6中的类和对象
类 (class)
- 创建类
class 类名{属性和方法} [构造函数语法糖]
class Person { constructor(name, age) { this.name = name this.age = age } sayHello() { console.log(`Hello, my name is ${this.name}`) } } // 类名首字母大写 类就是构造函数的语法糖
- constructor构造函数
class Star { constructor (uname,age){ this.uname = uname this.age = age } } // 属性:放到constructor构造函数里面
constructor()
方法是类的构造函数 (默认方法),用于传递参数,返回实例对象,通过new命令生成对象实例时,自动调用该方法- 注意
-
类里面的方法不带function,直接写即可
-
类里面要有属性方法,属性方法要是想放到类里面,我们用constructor构造器
-
构造函数作用:接收参数,返回实例对象,new的时候主动执行,主要放一些公共的属性
-
每个类里面一定有构造函数,如果没有显示定义, 类内部会自动给我们创建一个constructor()
-
this代表当前实力化对象,谁new就代表谁
-
- 类的继承
extends
子类继承父类// 定义父类 class Animal { constructor(name) { this.name = name } speak() { console.log(`${this.name} makes a noise.`) } } // 定义子类 class Dog extends Animal { constructor(name, breed) { super(name) // 调用父类的构造函数 this.breed = breed } speak() { console.log(`${this.name} barks.`) } getBreed() { return this.breed } }
super关键字
调用父类的方法(普通方法,构造方法)- super关键字用于访问和调用对象父类上的函数。可以调用父类的构造函数,也可以调用父类的普通函数
- 当子类没有constructor的时候可以随意用父类的,但是如果子类也含有的话,constructor会返回实例,this的指向不同,不可以再直接使用父类的东西
// 调用父类构造函数 class F { constructor(name, age){} } class S extends F { constructor (name, age) { super(name,age) } } // 注意: 子类在构造函数中使用super, 必须放到this 前面(必须先调用父类的构造方法,在使用子类构造方法) // 调用父类普通函数 class F { constructor(name, age){} say () {} } class S extends F { constructor (name, age) { super(name,age) } say () { super.say() } } // 注意:如果子类也有相同的方法,优先指向子类,就近原则
- 属性和方法
- 属性: 如果子类既想有自己的属性,又想继承父类的属性,那么我们用super [super(参数,参数)]
- 方法:如果子类和父类有相同的方法,假如子类依旧想用父类的属性,那么我们用super调用 [super.方法()]
- 如果子类不写东西,那么直接继承父类就可以用
- 如果子类有自己的构造函数和父类同名的方法,此时不可以直接用父类的东西,需要用super调用父类的方法和构造函数
- 注意
- 在ES6中 类 没有变量提升,所以必须先定义类,才能通过实例化对象
- 类里面的共有属性和方法一定要加this使用 [this,对象调用属性和方法]
- 类里面的this指向问题
- constructor里面的this指向实例对象
- 普通方法里面的this指向这个方法的调用者
对象
- 创建对象的三种方式
- 对象字面量
var obj = {}
- 构造函数
var obj = new Object()
- 自定义构造函数
var obj = new 类名()
function Person(uname,age) { this.uname = uname this.age = age this.chi = function() { console.log('吃') } } // 构造函数要和new结合使用 var obj = new Person('黄嘉文',22) console.log(obj) obj.chi()
- 对象字面量
- 构造函数
- 介绍:是一种特殊的函数,主要用来初始化对象,即为对象成员变量赋初始值,它总与new一起使用。我们可以把对象中一些公共的属性和方法抽取出来,然后封装到这个函数里面
- 使用注意事项
- 构造函数用于创建某一类对象,其首字母要大写
- 构造函数要和new一起使用才有意义
- new在执行时会做的事
- 在内存中创建一个新的空对象
- 让this指向这个新的对象
- 执行构造函数里面的代码,给这个新对象添加属性和方法
- 返回这个新对象 (所以构造函数里面不需要return)
- 原型
prototype
- 概念:是构造函数的一个属性,也是一个对象,称为原型对象
- 作用:共享方法,从而达到节省内存
function Star(uname, age) { this.name = uname this.age = age } Star.prototype.say = function () { console.log('方法') } var obj = new Star('小甜甜', 23) console.log(obj) obj.say() // Star也是对象 // 每一个构造函数都有prototype属性 // prototype是构造函数的一个属性 // 我们以后把方法都放到原型对象上面 console.log(Star.prototype)
- 注意:每一个构造函数都有prototype属性
- 总结:公共属性放到构造函数中,公共方法放到原型对象中
- 对象原型 proto
- 作用:指向原型对象
function Star(uname, age) { this.name = uname this.age = age } Star.prototype.say = function () { console.log('小甜甜') } // 构造函数,实例化对象 var obj = new Star('甜甜', 23) console.log(obj) // console.log(obj.__proto__ 等价于 Star.proto) console.log(Star.prototype) obj.say()
- 注意
- 每个对象都有一个__proto__
- __proto__是一个非标准属性,不可以拿来赋值或者设置【只读属性】
- 构造函数和原型对象都会有一个属性proto指向构造函数的prototype 原型对象,之所以我们对象可以使用构造函数prototype原型对象的属性和方法,就是因为对象有proto 原型的存在
- __proto__对象原型和原型对象prototype 是等价的
- __proto__对象原型的意义就在于为对象的查找机制提供一个方向,或者说一条路线,但是它是一个非标准属性,因此实际开发中,不可以使用这个属性,它只是内部指向原型对象prototype