面向对象概述(oop)
面向对象是一种编程思维(oop),将对应的你需要用到的对象进行提取,将对应方法综合到对应的对
象中,在需要调用对应的方法的时候去找对应的对象。(万物皆对象(任何东西都可以抽取为对象),
主要的过程就是找对应的对象做对应的事情。)
示例
相亲 (面向过程)过程中会产生很多的行为(行为比较分散)
找媒婆 (介绍人)
提需求 (你)
匹配人 (媒婆)
见面
相互了解
....
面向对象(主要是找对应的对象 去做对应的事情(忽略过程))
媒婆
我
相亲对象
面向对象的核心就是找对象
面向对象的三大特性
封装 (将对应的属性和方法抽取封装到对应的类(构造函数)中)
继承(子类继承父类 子类拥有父类非私有属性及方法)
多态(一个东西多种形态体(基于继承的) 重载(一个类多个函数重名(js中不允许的))重写(子类重写父类方法))
对象创建声明的方式
使用new关键词来声明 (实际调用的都是构造函数)
es6新增的class (其实调用也是构造函数)
class Person{
//类的构造器
constructor(name){
this.name = name
}
}
//调用类中的构造器
let person = new Person('jack')
es3自带的构造函数
function Person(name){
this.name = name
}
let person = new Person('tom')
构造函数和class的区别
构造函数的兼容会比class要好
构造函数会进行预编译 class不会进行预编译
构造函数他可以当作普通函数调用 class不行
new构造函数的时候主要过程
自动创建对象
手动属性赋值
自动返回对象
//对象工厂函数 (忽略细节)
function factory(name){
//创建一个对象
let obj = new Object()
//给对应的属性赋值
obj.name = name
//返回这个对象
return obj
}
let obj = factory('jack')
console.log(obj)
使用工厂函数的主要过程
手动创建对象
手动属性赋值
手动返回对象
封装
抽取对应的属性和方法 (属性为名词方法为动词)
示例
从前有座山 山里有个庙 庙里有老和尚 老和尚对小和尚说 山下的女人是老虎
对象的抽取
山
class Hill{
constructor(temple){
this.temple = temple //属性
}
}
庙
class Temple{
constructor(oldMonk){
this.monk = oldMonk //属性
}
}
老和尚、小和尚
class Monk{
constructor(name){
this.name = name //属性
this.say = function(monk){
console.log(`${this.name}对${monk.name}说山下的女人是老虎`)//方法
}
}
}
继承
子类继承父类的非私有属性及方法
示例
class的extends关键词来实现继承
//人类
class Person {
constructor(name, age) {
this.name = name
this.age = age
this.height = 180
this.eatFood = function () {
console.log(this.name + '在吃饭')
}
}
}
//使用学生类来继承人类
class Student extends Person {
constructor(name, age, score) {
super(name, age) //super指向对应的父类的构造函数
this.score = score
}
}
let student = new Student('张三', 18, 60)
console.log(student.name) //继承父类的属性
console.log(student.height) //继承父类的属性
student.eatFood() //继承父类的方法
console.log(student.score) //继承父类的属性
多态
一个内容的多种形态主要有俩个表现方式
重载 (在同一个类中有俩个同名的方法 通过参数个数及参数类型来分辨的)(JS没有重载)
class Person{
constructor(){
// this.sayHello = function(a){
// console.log(a)
// }
//覆盖上面的函数 因为对应的js是弱类型语言 不能强制指定类型 不能强制指定参数个数
// this.sayHello = function(a,b){
// console.log(a,b)
// }
//模拟实现
this.sayHello = function(a,b){
if(arguments.length==1){
console.log(a)
}
if(arguments.length==2){
console.log(a,b)
}
}
}
}
new Person().sayHello('hello')
new Person().sayHello('hello','world')
重写 (在子类中重写父类的方法)
class Person{
constructor(){
this.sayHello = function(){
console.log('父类的函数')
}
}
}
class Student extends Person{
constructor(){
super()
this.sayHello = function(){
console.log('重写的函数')
}
}
}
new Student().sayHello() //重写的函数
练习
编写⼀个动物类,该类包含name的属性,和say的⽅法。 通过say⽅法可以打印动物说话了。编写⼀个Dog类继承动物类,要求 该类中包含颜⾊的属性,该类重写say⽅法,要求打印⽗类的say⽅法⾥的内容,并且打印 动物颜⾊+动物名字+“叫了”。(备注狗会一直叫)
class Animal {
constructor(name) {
this.name = name
}
//先编译执行
say () {
console.log(this.name + '说话了')
}
}
class Dog extends Animal {
constructor(name, color) {
super(name)
this.color = color
this.fn = this.say //接收的父类的say方法
//重写say方法
this.say = function () {
let _this = this
this.fn()
setInterval(() => {
console.log(_this.color + _this.name + '叫了')
},1000)
}
}
}
let dog = new Dog('旺财', '土黄')
dog.say()
tab栏切换案例(面向对象)
提取属性 点击的按钮 切换的内容
提取方法 事件处理的方法 切换的方法
class Tab {
constructor(naviBar, content) {
this.naviBar = naviBar //传入的按钮
this.content = content //传入的内容
this.index = 0
//调用handler
this.handlerClick()
}
//切换对应的内容部分
toggle() {
//遍历对应的传入的按钮
//排他
Array.from(this.naviBar).forEach((btn) => {
btn.className = ''
})
this.naviBar[this.index].className = 'select'
//遍历对应的传入的内容
Array.from(this.content).forEach((v) => {
v.style.display = 'none'
})
this.content[this.index].style.display = 'block'
}
handlerClick() {
var that = this
//给对应的naviBar添加点击事件
Array.from(this.naviBar).forEach((btn, i) => {
btn.onclick = function () {
that.index = i
//切换
that.toggle()
}
})
}
//获取所有的a
var bar = document.querySelectorAll('.header>a')
//获取所有的内容
var content = document.querySelectorAll('.content>div')
new Tab(bar,content)
面向对象的拖拽
//拖拽的元素 属性
//拖拽的处理就是对应方法
class Drag {
constructor(element) {
this.element = element //拖拽的元素
//调用对应的鼠标事件
this.handlerMouseEvent()
}
//处理鼠标事件
handlerMouseEvent() {
//先按下
this.element.onmousedown = (e) => {
e = e || window.event
//记录按下的位置
let downPoint = {
x: e.offsetX,
y: e.offsetY
}
//再移动
document.onmousemove = (e) => {
e = e || window.event
//获取每次移动的位置
var target = {
x:e.pageX - downPoint.x,
y:e.pageY - downPoint.y
}
//设置对应的element
this.element.style.left = target.x + 'px'
this.element.style.top = target.y + 'px'
}
//再弹起
document.onmouseup = () => {
document.onmousemove = document.onmouseup = null
}
}
}
new Drag(document.querySelector('div'))