JS基础知识3---原型和原型链
2020-07-18 本文已影响0人
泡杯感冒灵
题目
- 如果判断一个变量是不是数组?
arr instanceof Array
- 手写一个建议的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)
})
}
}
// 插件,就是往jQuery原型上添加
jQuery.prototype.dialog = function(info){
alert(info)
}
// 造轮子,既可以用我们写的jQuery的东西,又可以用下边自己定义的东西
class myJquery extends jQuery {
constructor(selector){
super(selector)
}
// 扩展自己的方法
addClass(classname){
}
style(data){
}
}
const $p = new jQuery('p')
$p.get(2)
$p.each(elem=>{console.log(elem.nodeName)})
$p.on('click',()=>{alert('clicked')})
- class的原型本质,怎么理解?
原型和原型链的图
,属性和方法的执行规则
知识点
- class和继承
// ES6方式声明一个类
class Student {
constructor(name,age,number) {
this.name = name
this.age = age
this.number = number
}
sayHi() {
console.log(
`姓名${this.name}, 学号 ${this.number},年龄 ${this.age}`
)
}
}
// 通过类声明一个实例
const stu1 = new Student('小明', 20, 100)
console.log(stu1.name)
console.log(stu1.age)
console.log(stu1.number)
stu1.sayHi()
// 下边是继承
// 父类
class People{
constructor(name) {
this.name = name
}
eat() {
console.log(`${this.name} eat food`)
}
}
// 子类
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 mike = new Student('麦克', 200)
console.log(mike.name) // 麦克
console.log(mike.number) // 200
mike.eat() // 麦克 eat food
mike.sayHi() // 姓名 麦克 学号 200
// 老师实例
const teacherWang = new Teacher('王老师', '语文')
console.log(teacherWang.name) //王老师
console.log(teacherWang.major) // 语文
teacherWang.teach() //王老师 教授 语文
- 类型判断 instanceof
instanceof 判断原理就是,前边的变量顺着隐式原型往上找,能否找到后边的变量的显示原型,如果可以,就返回true
console.log(mike instanceof People) // true
console.log(mike instanceof Student) // true
console.log(mike instanceof Object) // true
console.log([] instanceof Array) // true
console.log([] instanceof Object) // true
console.log({} instanceof Object) // true
image.png
- 原型和原型链
// class 实际上是函数,可见是语法糖
typeof People // 'function'
typeof Student // 'function'
const xiaoming = new Student('小明',100)
console.log(xiaoming.__proto__) // People {constructor: ƒ, study: ƒ}
console.log(Student.prototype) // People { constructor: ƒ, study: ƒ }
console.log(xiaoming.__proto__ === Student.prototype) // true
原型关系:
每个class都有显示原型 prototype
每个实例都有隐式原型 __proto__
实例的__proto__ 指向对应class的prototype
关于原型的执行规则:
- 获取属性 xiaoming.name 和执行方法 xiaoming.sayHi()
- 现在自身属性和方法寻找
- 如果找不到,则自动去
__proto__
中查找
原型链
console.log(Student.prototype.__proto__)
console.log(People.protype)
console.log(Student.prototype.__proto__ === People.prototype) //true
重要提示
- class是ES6语法规范,由ECMA委员会发布
- ECMA只规定语法规则,即我们的书写规范, 不规定如何实现
- 以上实现方式,都是V8引擎的实现方式,也是主流