目錄
1.class和繼承
class
關於class的代碼如下,看起來還是蠻像java代碼的
// 類
class Student {
constructor(name, number) {
this.name = name // 這個對象裏新增一個name賦值爲傳進來的name
this.number = number
// this.gender = 'male'
}
sayHi() {
console.log(
`姓名 ${this.name} ,學號 ${this.number}`
)
// console.log(
// '姓名 ' + this.name + ' ,學號 ' + this.number
// )
}
// study() {
// }
}
// 通過類 new 對象/實例
const xialuo = new Student('夏洛', 100)
console.log(xialuo.name)
console.log(xialuo.number)
xialuo.sayHi()
const madongmei = new Student('馬冬梅', 101)
console.log(madongmei.name)
console.log(madongmei.number)
madongmei.sayHi()
運行結果
繼承
代碼如下,還是和java很像,主要看一下js中該怎麼用,記住這個例子,後面所有的講解圍繞這段代碼展開
// 父類
class People {
constructor(name) {
this.name = name
}
eat() {
console.log(`${this.name} eat something`)
}
}
// 子類
class Student extends People {
constructor(name, number) {
super(name)
this.number = number
}
sayHi() {
console.log(`姓名 ${this.name} 學號 ${this.number}`)
}
}
// 子類
class Teacher extends People {
constructor(name, major) {
super(name)
this.major = major
}
teach() {
console.log(`${this.name} 教授 ${this.major}`)
}
}
// 實例
const xialuo = new Student('夏洛', 100)
console.log(xialuo.name)
console.log(xialuo.number)
xialuo.sayHi()
xialuo.eat()
// 實例
const wanglaoshi = new Teacher('王老師', '語文')
console.log(wanglaoshi.name)
console.log(wanglaoshi.major)
wanglaoshi.teach()
wanglaoshi.eat()
運行結果:
經過我的測試,發現如果沒有構造器constructor,默認的賦值就不行,也不會和java一樣默認構造器,也不會默認調用super,不會報錯,相關變量只會undefined
類型判斷-instanceof
還是接着上面的繼承的例子來看
注意細節:剛剛在Student中定義的方法sayHi(),結果在Student的原型Student.prototype中
有小夥伴已經摸索出來了,到底instanceof是怎麼樣的呢?我們看看原型再來說明instanceof
2.原型
控制檯看一下
Student.prototype和xialuo.__pro__的關係如下
剛剛在Student中定義的方法sayHi(),結果在Student的原型Student.prototype中,所以可以說明在class中定義的方法是在這個class的prototype中的,是所有實例共同擁有的。
原型關係
每個class都有顯式原型prototype
每個實例都有隱式原型__proto__
實例的__proto__指向對應class的prototype
基於原型的執行規則
獲取屬性xialuo.name或執行方法xialuo.sayHi()時,先在自身屬性和方法尋找,如果找不到則自動去__pro__中查找
3.原型鏈和instanceof
運行結果如下
原型鏈
xialuo是new Student出來的,是一個Student對象,xialuo的__proto__等於Student的Prototype
這裏People.prototype和Student.prototype.__proto__是相等的,也可以認爲Student.prototype是new出來People對象
People.prototype.__proto__和Object.prototype是相等的,那麼可以認爲People.prototype是new出來的Object對象
Student.prototype instanceof People 爲true
People.prototype instanceof Object 也爲true
這個關係真的好奇妙啊
我是你new出來的,我的隱式__pro__等於你的顯式prototype
反過來也是,我的隱式__pro__等於你的顯式prototype,那麼我就是你new出來的對象
再看instanceof
直接總結:A instanceof B成立的條件爲
左邊A的隱式__proto__鏈上能找到一個等於右邊B的顯式prototype則爲true,否則爲false
提示:
4.練習題
1.如何判斷準確判斷一個變量是不是數組?
A instanceof Array
2.class方法的本質?
在class Student中定義的方法sayHi(),結果在Student的原型Student.prototype中,所以可以說明在class中定義的方法是在這個class的prototype中的,這樣才能實現new出來的實例都有這個方法
獲取屬性或執行方法時,先在自身屬性和方法尋找,如果找不到則自動去__pro__中查找
3.手寫簡易jQuery考慮插件和擴展性
更方便理解class和原型
class jQuery {
constructor(selector) {
const result = document.querySelectorAll(selector) // 返回NodeList
const length = result.length
for (let i = 0; i < length; i++) {
this[i] = result[i]
}
this.length = length
this.selector = selector
}
get(index) {
return this[index]
}
each(fn) {
for (let i = 0; i < this.length; i++) {
const elem = this[i]
fn(elem)
}
}
on(type, fn) {
return this.each(elem => {
elem.addEventListener(type, fn, false)
})
}
// 擴展很多 DOM API
}
// 插件
jQuery.prototype.dialog = function (info) {
alert(info)
}
// “造輪子”
class myJQuery extends jQuery {
constructor(selector) {
super(selector)
}
// 擴展自己的方法
addClass(className) {
}
style(data) {
}
}
// const $p = new jQuery('p')
// $p.get(1)
// $p.each((elem) => console.log(elem.nodeName))
// $p.on('click', () => alert('clicked'))
測試代碼:
index.js
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>js 基礎知識 演示</title>
</head>
<body>
<p>一段文字 1</p>
<p>一段文字 2</p>
<p>一段文字 3</p>
<script src="./jquery-demo.js"></script>
</body>
</html>
我們來看看再控制檯的運行顯示
點擊p元素後顯示如下
然後再添加on監聽事件
鼠標移動到p則顯示
關注、留言,我們一起學習。
===============Talk is cheap, show me the code================