5 - 原型、原型链

215 阅读1分钟

题目

  • 如何准确判断一个变量是不是数组?
    • a instanceof Array
  • class的原型本质,怎么理解?
    • 原型和原型链的图示
    • 属性和方法的执行规则
  • 手写一个简易的jQuery,考虑插件和扩展性
    • 题解放到最后面

知识点

  • class 和继承
  • 类型判断instanceof
  • 原型和原型链

如何使用class

class使用演示:

class Student{
    constructor(name,number){
        this.name = name;
        this.number = number;        
    }
    sayHi(){
        console.log(`name: ${this.name}, number: ${this.number}`);
    }
}

//通过类 new 对象/实例
const xialuo = new Student('夏洛',101);
console.log(xialuo.name)
console.log(xialuo.number)
xialuo.sayHi()

继承

  • extends
  • super
  • 扩展或重写方法
//父类
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(`name: ${this.name}, number: ${this.number}`);
    }
}
//子类
class Teacher extends People{
    constructor(name,major){
        super(name)
        this.major = major
    }
    teach(){
        console.log(`${this.name} 教授 ${this.major}`)
    }
}
//通过类 new 对象/实例
const xialuo = new Student('夏洛',101);
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()

类型判断 - instanceof

通过[继承]一节的例子来看

xialuo instanceof Student //true
xialuo instanceof People //true
xialuo instanceof Object //true

[] instanceof Array //true
[] instanceof Object //true

{} instanceof Object //true

原型

//class 实际上是函数,可见是语法糖
typeof People //'function'
typeof Student //'function'

//隐式原型和显示原型
console.log(xialuo.__proto__)
console.log(Student.prototype)
console.log(xialuo.__proto__ === Student.prototype) //true

image.png

image.png

image.png

image.png

原型图表 image.png

原型关系

  • 每个class都有显示原型prototype
  • 每个实例都有隐式原型__proto__
  • 实例的__proto__指向对应class的prototype

基于原型的执行规则

  • 获取属性xialuo.name或执行方法xialuo.sayhi()时,先在自身属性和方法寻找
  • 如果找不到则自动去__proto__中查找

原型链

console.log(Student.prototype.__proto__)
console.log(People.prototype)
console.log(People.prototype === Student.prototype.__proto__) 

image.png

判断属性是否属于自己

xialuo.hasOwnProperty('eat') //false
xialuo.hasOwnProperty('hasOwnProperty') //false

手写一个简易的jQuery,考虑插件和扩展性

//简易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;
    }
    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
}

//const $p = new jQuery('p')
//$p.get(1)
//$p.each((elem) => console.log(elem.nodeName))
//$p.on('click',() => alert('clicked'))

/*
//造轮子  -- 只是一个假设
class myJQuery extends jQuery{
    constructor(selector){
        super(selector)
    }
    //扩展自己的方法
    addClass(className){}
}*/

image.png

image.png