目录
![](/qrcode.jpg)
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================