概述:面向?qū)ο笫且环N編程思想(oop),面向?qū)ο髮τ诿嫦蜻^程的一個抽取與簡化。主要由類來構(gòu)建對象,以對象來儲存對應(yīng)的行為和屬性,抽取對應(yīng)的行為作為方法,抽取對應(yīng)的屬性作為屬性。
核心:萬物皆對象(所有的容器都可以抽取為一個對象)
關(guān)鍵點:找有這個行為的對象去完成這個行為
面向?qū)ο蠛兔嫦蜻^程
面向過程
以過程為核心
例:
- 找飯店
- 點餐
- 等菜
- 吃飯
- 結(jié)賬
面向?qū)ο?/h3>
以對象為核心
例:
- 我找飯店(對象:我、飯店)
- 點餐、吃飯、結(jié)賬(我的行為)
- 飯店提供食物的過程(飯店的行為)
對象的構(gòu)建
調(diào)用new關(guān)鍵詞,執(zhí)行對應(yīng)的構(gòu)造函數(shù)來構(gòu)建對象
通過類來構(gòu)建對象(es6)構(gòu)造器
class Person{
constructor(username){
this.name = username
}
}
var person = new Person('jack')
通過構(gòu)造函數(shù)來構(gòu)建(es3)
//以構(gòu)造函數(shù)構(gòu)建 首字母大寫
function Dog(name){
this.name = name //函數(shù)里面的this指向它的調(diào)用者 在new的時候指向?qū)?yīng)的對象實例
}
var dog = new Dog('旺財')
上述兩種方式核心都是通過構(gòu)造函數(shù)(構(gòu)建對象的函數(shù))來構(gòu)建
構(gòu)造函數(shù)構(gòu)建做了什么操作
- 自動構(gòu)建對象
- 手動設(shè)置屬性
- 自動返回對象
通過工廠模式構(gòu)建對象
- 手動創(chuàng)建對象
- 手動設(shè)置屬性
- 手動返回對象
//以工廠模式來構(gòu)建
//工廠里面要傳入對應(yīng)的屬性 返回對應(yīng)的對象(不能區(qū)分類型)
function factory(name){
//Object是最大的對象 手動構(gòu)建對象
var obj = new Object()
//手動給obj設(shè)置相關(guān)的屬性
obj.name = name
//手動返回對應(yīng)的對象
return obj
}
//調(diào)用
var obj = factory('旺財')
var obj1 = factory('jack')
console.log(obj,obj1);
工廠模式的特性
- 可以構(gòu)建所有對象
- 構(gòu)建對象時會忽略細節(jié)
- 構(gòu)建的對象都是Object(instabceof全部指向Object)
console.log(obj instanceof Object);//true
console.log(obj1 instanceof Object);//true
面向?qū)ο蟮娜筇匦?/h1>
- 封裝(將對應(yīng)的行為抽取為方法)
- 繼承(子類繼承父類的屬性和方法)
- 多態(tài)(繼承關(guān)系的體現(xiàn),js不允許子類重寫父類的方法,在一個類有兩個同名的方法,沒有重載)
例:
有一個貓會喵喵叫 很胖800斤 吃的很多 名字叫咪咪
屬性: 體重800 名字咪咪
方法: 喵喵叫 吃的很多
繼承與對應(yīng)的重寫
class Person{
constructor(){
// var sex = '男'
this.name = 'jack'
this.say = ()=>{
console.log('哈哈哈哈');
}
}
}
class Son extends Person{
constructor(age){
super() //調(diào)用Person的constructor
this.age = age
//重寫
this.say = ()=>{
console.log('嘻嘻嘻嘻');
}
}
}
var son = new Son()
console.log(son);//name say age
son.say() //嘻嘻嘻嘻
面向?qū)ο蟮膖ab欄切換
例:
有一個貓會喵喵叫 很胖800斤 吃的很多 名字叫咪咪
屬性: 體重800 名字咪咪
方法: 喵喵叫 吃的很多
class Person{
constructor(){
// var sex = '男'
this.name = 'jack'
this.say = ()=>{
console.log('哈哈哈哈');
}
}
}
class Son extends Person{
constructor(age){
super() //調(diào)用Person的constructor
this.age = age
//重寫
this.say = ()=>{
console.log('嘻嘻嘻嘻');
}
}
}
var son = new Son()
console.log(son);//name say age
son.say() //嘻嘻嘻嘻
屬性:tab欄、提示框
方法:tab欄的點擊事件,切換顯示欄的方法
//構(gòu)建一個類
class Tab{
constructor(nav,contents){
this.nav = nav //上邊的點擊欄
this.contents = contents //下面的切換的內(nèi)容
this.selectIndex = 0
this.handlerClick()
}
//切換的方法
toggle(selectElement){
//選中內(nèi)容變成對應(yīng)的樣式為selected 其他排他
Array.from(this.nav).forEach((item)=>{
item.className = ''
})
selectElement.className = 'selected';
// this.nav[this.selectIndex].className = 'selected'
//下面切換內(nèi)容 樣式為show
Array.from(this.contents).forEach((item)=>{
item.className = ''
})
//根據(jù)你傳入的元素來查找下標(biāo)
let i = Array.from(this.nav).findIndex((v)=>{
return v == selectElement
})
this.contents[i].className = 'show'
}
//點擊事件處理
handlerClick(){
let _this = this
Array.from(this.nav).forEach((item,i)=>{
item.onclick = ()=>{
// _this.selectIndex = i
_this.toggle(item)
}
})
}
}
面向?qū)ο笸献崿F(xiàn)
// 拖拽實現(xiàn)
// 屬性 包含拖拽盒子的大盒子 拖拽的盒子 盒子的坐標(biāo)位置
class Touch {
constructor(outerBox, move) {
this.outerBox = outerBox //包含的盒子
this.move = move //移動的盒子
this.point = { //坐標(biāo)位置
x: parseInt(this.getStyle(move).left) || 0,
y: parseInt(this.getStyle(move).top) || 0
} //基礎(chǔ)坐標(biāo)為0,0
this.handlerDown()
}
//獲取樣式的方法
getStyle(element) {
return window.getComputedStyle ? window.getComputedStyle(element, '') : element.currentStyle
}
//按下
handlerDown(){
this.move.onmousedown = (e)=>{
e = e || window.event
//獲取第一次按下的位置
let currentX = e.offsetX
let currentY = e.offsetY
//調(diào)用移動的方法
this.handlerMove(currentX,currentY)
//調(diào)用彈起的方法
this.handlerUp()
}
}
//彈起
handlerUp(){
document.onmouseup = ()=>{
this.outerBox.onmousemove = null
}
}
//移動
handlerMove(currentX,currentY){
//給大盒子添加移動事件
this.outerBox.onmousemove = (e) => {
e = e || window.event
//大盒子在頁面上的位置
let { x, y } = this.getPagePoint(this.outerBox)
//獲取移動的位置 - 大盒子在頁面上的位置 - 當(dāng)前按下位置
let { targetX, targetY } = {
targetX: e.pageX - x - currentX,
targetY: e.pageY - y - currentY
}
let { maxX, maxY } = {
maxX: this.outerBox.offsetWidth - this.move.offsetWidth,
maxY: this.outerBox.offsetHeight - this.move.offsetHeight
}
//區(qū)間判斷
if (targetX < 0) {
targetX = 0
}
if (targetX > maxX) {
targetX = maxX
}
if (targetY < 0) {
targetY = 0
}
if (targetY > maxY) {
targetY = maxY
}
//將對應(yīng)的位置設(shè)置進去
this.point = { x: targetX, y: targetY }
this.setMovePoint()
}
}
setMovePoint() {
//設(shè)置
this.move.style.left = this.point.x + 'px'
this.move.style.top = this.point.y + 'px'
}
getPagePoint(element) {
let x = 0
let y = 0
while (element.offsetParent) {
x += element.offsetLeft
y += element.offsetTop
element = element.offsetParent
}
return { x, y }
}
}
基于面向拖拽的實現(xiàn)(放大鏡)
//放大鏡功能和區(qū)間拖拽的實現(xiàn)有類似
class Magnifier extends Touch {
constructor(smallBox, moveBox, bigBox, bigImage) {
//傳給父類
super(smallBox, moveBox) //outerBox move
this.bigBox = bigBox
this.bigImage = bigImage
this.handlerEnter()
this.handlerLeave()
}
handlerEnter() {
this.outerBox.onmouseenter = () => {
this.move.style.display = 'block'
this.bigBox.style.display = 'block'
this.init()
//調(diào)用移動的方法
this.handlerMove(this.move.offsetWidth / 2, this.move.offsetHeight / 2)
}
}
handlerLeave() {
this.outerBox.onmouseleave = () => {
this.move.style.display = 'none'
this.bigBox.style.display = 'none'
}
}
init() {
//將移動的move的大小初始化
this.move.style.width = this.outerBox.offsetWidth / (this.bigImage.offsetWidth / this.bigBox.offsetWidth) + 'px'
this.move.style.height = this.outerBox.offsetHeight / (this.bigImage.offsetHeight / this.bigBox.offsetHeight) + 'px'
}
setMovePoint() {
//根據(jù)對應(yīng)的坐標(biāo)來設(shè)置對應(yīng)的位置
//設(shè)置
this.move.style.left = this.point.x + 'px'
this.move.style.top = this.point.y + 'px'
//設(shè)置大圖片的位置
// 外面的盒子/移動的盒子 = 大的圖片/大的盒子
// 350 / ? = 800 / 540
// 350 = (800 / 540 ) * ? ==> ? = 350 / (800 / 540)
// 150 / 350 == 大的圖片移動多少 ?/800
// 150 / 350 = ?/800 ===> ? = 150/350*800
let x = this.point.x / this.outerBox.offsetWidth * this.bigImage.offsetWidth * -1
let y = this.point.y / this.outerBox.offsetHeight * this.bigImage.offsetHeight * -1
//設(shè)置大圖片的定位
this.bigImage.style.left = x + 'px'
this.bigImage.style.top = y + 'px'
}
}