js本身是一个基于原型的语言,最初我们的继承只能依靠原型做继承;后来引入了es5 es6 我们可以拿Class做继承;其实Class内部还是一个原型的继承;
讲解过程:
- 先拿出题目
- 再透过题目看知识点
- 最后解答
题目
- 如何准确判断一个变量是不是数组?
- 手写一个简易的jQuery,考虑插件和扩展性(为了更好的学习js学习内部思路)
- class的原型本质,怎么理解?通过自己的语言把原型和本质表述出来
知识点
- Class和继承
- 类型判断 instanceof
- 原型和原型链
class
Class是一个面向对象的语法实现,Class其实很像一个模板,我们可以通过模板去构建一些东西。
- constructor
- 属性
- 方法
class的原型本质:
- 原型和原型链的图示(自己画一遍)
- 属性和方法的执行规则
class Student {
constructor(name,number){
this.name = name
this.number = number
// 可以赋更多属性
}
siHi(){
console.log(`妹子${this.name}想打酱油${this.number}`)
}
study(){...可以直接写多个方法..}
}
通过类class 创造实例
const xiaorongrong = new Student('小熔熔',100)
console.log(xiaorongrong)
xiaorongrong.siHi()
复制代码
继承
- extends
- super
- 扩展或重写的方法
直接打印一个未声明的变量会报错 xxx is not defined
但直接打印一个对象内不存在的值会是undefined
复制代码
// 父类
class People {
constructor(name){
this.name = name
}
eat(){
console.log(`${this.name}是一个漂亮妹子`)
}
}
// 子类 继承的话要记得在constructor内super
class Student extends People {
constructor(name,number){
super(name)
this.number = number
}
sayHi(){
console.log(`姓名${this.name}漂亮妹子还对你招了手`)
}
}
// 再写一个继承People的子类
class Teacher extends People {
constructor(name,major) {
super(name)
this.major = major
}
teacher(){
console.log(`${this.name}教授${this.major}`)
}
}
// 实例
const xialuo = new Student('夏洛', 100)
console.log(xialuo.name) //夏洛
console.log(xialuo.Siholll)//undefined
xialuo.sayHi()
xialuo.eat()
xialuo instanceof Student // true
xialuo instanceof People // true
复制代码
原型
继续刚才继承的例子
typeof People // function
typeof Student // function
console.log(xialuo._proto_) // sayHi() 隐式原型
console.log(Student.prototype) // sayHi() 显示原型
console.log(xialuo._proto_ === Student.prototype) // true
画一下这部分的原型链
复制代码
原型关系:
每个class都有显示原型prototype
每个实例都有隐式原型_proto_
实例的_prop_指向对应class构造函数的prototype
复制代码
原型链
继续刚才的例子
console.log(Student.prototype._proto_)
console.log(People.prototype)
console.log(People.prototype === Student.prototype._proto_)
复制代码
xialuo.hasOwnProperty('name')// true
xialuo.hasOwnProperty('sayHi')// false
复制代码
类型判断-instanceof
[] instanceof Array // true
[] instanceof Object // true
{} instanceof Object // true
复制代码
其实instanceof内部做了一个先从变量下查找有没有该元素,如果没有的话就顺着去该元素的_prop_上去寻找,一个原型链的顺序找到最顶端,如果都没找到才会返回false,如果能找到就返回true
提示
1.class是ES6语法规范,由ECMA委员会发布
2.ECMA 只规定语法规则,代码的书写规范,不规定如何实现
3.以上说的都是V8引擎的实现方式,也是主流的
复制代码
手写简易jQuery考虑插件和扩展性代码演示
主要看看它的基本结构,了解原型和继承
js:
// 一开始直接声明jQuery的类
class jQuery {
// 构造器
constructor(selector){
const result = document.querySelectorAll(selector)
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
}
复制代码
我们可以在控制台打印一下
html:
<body>
<p>一段文字 1</p>
<p>一段文字 2</p>
<p>一段文字 3</p>
<script src="https://juejin.cn/post/promise-demo.js"></script>
</body>
const $p = new jQuery('p')
console.log($p)
// jQuery{0:p, 1:p, 2:p, length:3, selector:"p",_proto_:Object}
$p.get(1) // <p>一段文字 2</p>
$p.each((elem) => console.log(elem.nodeName)) // 3p (3个p)
$p.on('click', ()=>alert('clicked'))
复制代码
考虑插件的扩展性:
// 插件
js=> 利用原型 把方法挂载在原型上
jQuery.prototype.dialog = function (info){
alert(info)
}
console=>
const $p = new jQuery('p')
$p.dialog()
// 复写/“造轮子” 这种就类似于,让大家用自己的插件,自己的插件继承于原对象
class myJQuery extends jQuery {
constructor(selector){
super(selector) // 继承所有父类
// 扩展自己的方法
addClass(){
}
style(data){
}
}
}
复制代码
小结
- class和继承,结合手写JQuery的示例来调整
- instanceof
- 原型和原型链:图示&执行规则
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END