前言
首先我们要了解什么是面向过程与面向对象:
- 面向过程:以过程为中心的思想,编程的时候把解决问题的步骤分析出来,然后用函数把这些步骤实现,再一步一步的具体步骤中再按顺序调用函数。以做的步骤划分问题。
- 面向对象:把事物分解成一个个对象,然后由对象之间分工与合作。它是以对象功能来划分问题,而不是步骤。
特性:封装性、继承性、多态性
JS是一种基于对象(object-based)的语言。是一种不完全面向对象的语言,它提供了可模拟面向对象的方式。
一、类与对象?
类(class)是对象(object)的模板,定义了同一组对象共有的属性和方法。即类时抽象的模板,对象是模板具体的实现。
二、用法详解
1.ES5中实现类与继承
// 类
function People(name, age) {
// console.log(this)
// 实例属性 定义在构造函数中
this.name = name
this.age = age
People.count++
}
// 静态属性 定义在main中
People.count = 0
// 静态方法
People.getCount = function(){
console.log(this.age) // undefined, 因为当前的this指向的是构造函数
console.log('当前共有' + People.count + '个人')
}
// 实例方法
People.prototype.showName = function () {
console.log('我的名字是' + this.name)
}
let p1 = new People('kakaDorothy', 20)
console.log(p1)
p1.showName()
let p2 = new People('Wengweng', 22)
console.log(p2)
p2.showName()
console.log(People.count)
People.getCount()
ES5中静态方法的继承:
// 父类
function Animal(name) {
this.name = name
}
//实例方法
Animal.prototype.showName = function () {
console.log('名字是:' + this.name)
}
// 子类
function Dog(name, color) {
Animal.call(this, name) // 继承属性,但并不能继承父类的方法
this.color = color
}
// 解决方法:将Dog的原型指向Animal对象,然后将构造函数指回到Dog上,这样便能继承父类的方法了
Dog.prototype = new Animal()
Dog.prototype.constuctor = Dog
let d1 = new Dog('wangwang', 'white')
console.log(d1)
d1.showName()
2. ES6中实现类与继承
使用class(ES6的语法糖)来定义类;使用get定义,set改变实例属性;使用static定义静态方法 ;ES6不能在class内定义静态属性。
class People {
constructor(name, age) {
// 实例属性定义在constructor下面
this.name = name
this.age = age
this._sex = -1
}
// static count = 0
// ES6中可将属性定义在构造方法的顶层
// 使用get定义,set改变
get sex() { // 属性
if (this._sex === 1) {
return 'male'
} else if (this._sex === 0) {
return 'female'
} else {
return 'error'
}
}
// 注意要避免生成死循环,定义_sex
set sex(val) { // 1:male 0:female
if (val === 0 || val === 1) {
this._sex = val
}
}
//实例方法
showName() {
console.log(this.name)
}
// 使用static定义静态方法
static getCount() {
return 5
}
}
// 静态属性
People.count = 9
console.log(typeof People) // function
console.log(People.count) // 9
let p1 = new People('kakaDorothy', 20)
console.log(p1)
p1.sex = 5 // 赋值不成功
console.log(p1.sex)
console.log(People.getCount()) // 5,此处不是p1.getCount(),不要再实例上调用,要在类上面调用
//Coder继承父类People
class Coder extends People {
constructor(name, age, company) {
//要继承父类的属性,需要使用super关键字
super(name, age)
this.company = company
}
showCompany() {
console.log(this.company)
}
}
let c1 = new Coder('Wengweng', 22, 'KD')
console.log(c1)
c1.showName()
c1.showCompany()
c1.sex = 1
console.log(c1.sex) //male
console.log(Coder.getCount()) //5
总结
ES6的方法更加简洁,可读性更强,也能实现一些拦截操作,所以更安全。