前端面试题3--JS基础--原型和原型链

160 阅读1分钟

1.原型和原型链

  • js 是基于原型继承的语言
  • class 是面向对象的语法的实现,class 本质上类似于一个模板

class

  • constructor // 构建
  • 属性
  • 方法
class Student { // 类名首字母大写
    constructor (name, number) {
        this.name = name
        this.number = number
    }
    sayHi () {
        console.log(`姓名${this.name},学号${this.nember}`)
    }
}
// 通过类声明对象/实例
const xixi = new Student('茜茜', 10001)
console.log(xixi.name)
console.log(xixi.number)
xixi.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(`姓名${this.name},学号${this.nember}`)
    }
}
const xixi = new Student('茜茜', 10001)
console.log(xixi.name)
console.log(xixi.number)
xixi.sayHi()
xixi.eat()

类型判断 - instanceof

xixi instanceof Student      // true
xixi instanceof People       // true
xixi instanceof Object       // true
[] instanceof Array          // true
[] instanceof Object         // true
{} instanceof Object         // true
// 所有引用类型的父类都是 Object
// instanceof 顺着隐式原型往上找能不能找到

原型

// class 实际上是函数,可见是语法糖
typeof People     // 'function'
typeof Student    // 'function'
// 隐式原型和显式原型
console.log(xixi._proto_)
console.log(Student.prototype)
console.log(xixi._proto_ === Student.prototype)

原型关系

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

基于原型的执行规则

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

原型链

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

验证是否是自身属性 hasOwnProperty

xixi.hasOwnProperty('name')    // true
xixi.hasOwnProperty('sayHi')   // false

2.如何准确判断一个变量是数组

  • a instanceof Array

3.class的原型本质

  • 原型和原型链的图示
  • 属性和方法的执行规则

4.手写简易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[i]
    }
    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.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'))


5.小结

  • class和继承,结合上面手写jQuery的示例来理解
  • instanceof
  • 原型和原型链:图示&执行规则 提示:class 是ES6语法规范,由ECMA委员会发布。ECMA只规定语法规则,即我们代码的书写规范,不规定如何实现。以上实现方式都是 V8 引擎的实现方式,也是主流的。