原型和原型链

87 阅读2分钟

原型和原型链

原型链

由一个例子开始,先来看这段代码:

// 父类
class Person {
  constructor(name) {
    this.name = name
  }
  Hello() {
    console.log(`hello, my name is ${ this.name }`);
  }
}

// 子类
class Student extends Person {
  constructor(name, age) {
    super(name)
    this.age = age
  }
  getAge() {
    console.log(this.age);
  }
}

这就是es6中简单的一个继承关系,而我们今天的演示也从它开始,来看看以下代码打印结果,思考为什么会出现这种这个结果:

console.log(airhua.__proto__); // 隐式原型
console.log(Student.prototype); // 显式原型
console.log(Student.prototype === airhua.__proto__); // true
console.log(Student.prototype.__proto__ === Person.prototype); // true
console.log(Person.prototype.__proto__ === Object.prototype); // true
console.log(Object.prototype.__proto__ === null); // true

为了解决这个问题,我们先了解一下引用类型的四个规则:

  1. 引用类型,都具有对象特性,即可自由扩展属性。

  2. 引用类型,都有一个隐式原型 __proto__ 属性,属性值是一个普通的对象。

  3. 引用类型,隐式原型 __proto__ 的属性值指向它的构造函数的显式原型 prototype 属性值。

  4. 当你试图得到一个对象的某个属性时,如果这个对象本身没有这个属性,那么它会去它的隐式原型 __proto__(也就是它的构造函数的显式原型 prototype)中寻找。

这也便是原型链的原理,我们可以用一张图片来解释上面的代码和规则:

1643379410264.png

最后一个 null,设计上是为了避免死循环而设置的, Object.prototype 的隐式原型指向 null

也就是说所有引用类型的顶层都是一个Object,正印证了那句’JavaScript 里万物皆对象‘

了解了这些,我们可以来手写一个简易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
        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) {
        
    }
}