這一段時間都在回顧和總結(jié)之前JS中一些比較重要的內(nèi)容,再次寫個日記鉴未,記錄下
面向?qū)ο蟮娜筇卣鳎?br>
1.封裝
2.繼承
3.多態(tài)
封裝
封裝是指創(chuàng)建一個對象集中保存一個事物的屬性與功能:
封裝對象有三種方式:
:直接用{}
var obj = {}
var obj1 = {
name: '本澤鍋',
foo: function() {
console.log(`I'm ${name}`)
//這里直接用name會報錯,Uncaught ReferenceError: name is not defined
//原因就是對象的{}不是作用域鸠姨,函數(shù)foo的作用域鏈只有自己和頂層的window铜秆,顯然會報錯
//解決方法:
console.log(`I'm ${this.name}`)
//這里就是 this的第一種情況:在普通函數(shù)中的this,指向的是調(diào)用當(dāng)前函數(shù)的.前的對象
}
}
console.log('obj', obj)
console.log('obj1', obj1)
:通過new關(guān)鍵詞新建對象
var obj = new Object()
console.log('obj',obj)
var obj1 = new Object()
obj1.name = '本澤鍋'
:通過構(gòu)造函數(shù)的方式
function Student (name,foo) {
//將來要加入到新對象中的屬性和方法
this.name = name
this.foo= foo
//這里就是 this的第二種情況:在構(gòu)造函數(shù)中的this,指向的是new創(chuàng)建的新對象
}
// 實例化1
var obj = new Student()
console.log('obj',obj)
// 實例化2
var obj1 = new Student('本澤鍋',function (){
})
console.log('obj1',obj1)
obj1.foo()
總結(jié): 通過構(gòu)造函數(shù)的方式創(chuàng)建對象 一共干了4件事
1.創(chuàng)建了一個新的空對象。
2.讓子對象繼承構(gòu)造函數(shù)的原型對象讶迁。(將子對象的隱式原型__proto__指向創(chuàng)建該構(gòu)造函數(shù)的顯示原型prototype上)
3.調(diào)用構(gòu)造函數(shù)连茧,將this替換為新對象,通過強(qiáng)行賦值的方式為新對象添加屬性和方法巍糯。
4.返回新對象的地址值啸驯。
繼承
繼承是父對象中的成員,子對象無需重復(fù)創(chuàng)建祟峦,就可以直接使用坯汤。
js中的幾種都是通過原型對象來實現(xiàn)的。
原型對象:替所有子對象集中保存共有屬性和方法的父對象搀愧。
概念:每一個構(gòu)造函數(shù)都有一個顯示原型ptototype.
每一個對象都有一個隱式原型proto惰聂,對象的隱式原型指向創(chuàng)建該構(gòu)造函數(shù)的顯示原型
當(dāng)我們通過構(gòu)造函數(shù)實例化一個對象的時候疆偿,就會自動將子對象的隱式原型指向創(chuàng)建該構(gòu)造函數(shù)的顯示原型,這樣就達(dá)到了繼承的目的搓幌。
原型執(zhí)行規(guī)則
當(dāng)我們獲取對象的屬性或者方法時杆故,首先在自身查找,如果有的話就使用溉愁,如果沒有的話处铛,就自動去隱示原型proto中去查找,而隱示原型會指向創(chuàng)建該對象構(gòu)造函數(shù)的顯示原型prototype去查找
原型鏈
當(dāng)訪問一個對象的某個屬性時拐揭,會先在這個對象本身屬性上查找撤蟆,如果沒有找到,則會去它的proto隱式原型上查找堂污,即它的構(gòu)造函數(shù)的prototype家肯,如果還沒有找到就會再在構(gòu)造函數(shù)的prototype的proto中查找,這樣一層一層向上查找就會形成一個鏈?zhǔn)浇Y(jié)構(gòu)盟猖,我們稱為原型鏈讨衣,直到找到頂端Object的顯示原型prototype,而Object的顯示原型prototype中隱示原型proto為null式镐,這樣就停止了反镇。
向原型對象中添加共有屬性和方法:
function Student (name,foo) {
this.name = name
this.foo= foo
}
//只能通過強(qiáng)行賦值的方法
Student.prototype.location= '武漢'
Student.prototype.study=function(){
console.log(this.name,'student')
//這里就是 this的第三種情況:原型對象中共有方法里的this,將來調(diào)用這個共有方法的.前的那個子對象
}
多態(tài):
同一個函數(shù),在不同情況下表現(xiàn)出的不同的狀態(tài)娘汞。
面向?qū)ο笮〗Y(jié):
1歹茶、封裝: 創(chuàng)建對象,2種:
如果只創(chuàng)建一個對象: {} 如果反復(fù)創(chuàng)建多個相同結(jié)構(gòu)的對象: 構(gòu)造函數(shù)
2你弦、繼承: 所有子對象共用的屬性值和方法惊豺,都要 放在構(gòu)造函數(shù)的原型對象中
3、多態(tài): 重寫: 只要覺得從父對象繼承來的成員 不要用鳖目,都在子對象中重寫同名成員
this的幾種情況:
1. obj.fun() this->.前的obj對象
2. new構(gòu)造函數(shù)() this->new正在創(chuàng)建的新對象
3. 構(gòu)造函數(shù).prototype.fun=function(){}
因為將來原型對象中的方法,都是”子對象.fun()”方式調(diào)用缤弦。 所以领迈,this->將來調(diào)用這個fun函數(shù)的.前的某個子對象
4. fun()、匿名函數(shù)自調(diào)和回調(diào)函數(shù)中的 this->window
5. button.onclick=function(){}或button.addEventListener(“click”,function(){...}) DOM事件處理函數(shù)里的
this-> 當(dāng)前正在出發(fā)事件的.前的DOM元素對象碍沐。
6. 箭頭函數(shù)中的this->當(dāng)前函數(shù)之外最近的作用域中的this
- 幾乎所有匿名函數(shù)都可用箭頭函數(shù)簡化
- 箭頭函數(shù)是對大多數(shù)匿名函數(shù)的簡寫
箭頭函數(shù)底層相當(dāng)于.bind() 永久綁定外部this
7. 改變this的指向
其實狸捅,對于this,我們不一定逆來順受
? - 可用call或apply累提,臨時替換一次函數(shù)中的this
? - 可用bind尘喝,永久替換函數(shù)中的this
總結(jié):
? a. 只在一次調(diào)用函數(shù)時,臨時替換一次this: call
? b. 既要替換一次this斋陪,又要拆散數(shù)組再傳參: apply
? c. 創(chuàng)建新函數(shù)副本谋右,并永久綁定this: bind