乐趣区

关于前端:原型与原型链面试回顾

深拷贝

/**
 * 深拷贝
 * @param {Object} obj 要拷贝的对象
 */
function deepClone(obj = {}) {if (typeof obj !== 'object' || obj == null) {
        // obj 是 null,或者不是对象和数组,间接返回
        return obj
    }

    // 初始化返回后果
    let result
    if (obj instanceof Array) {result = []
    } else {result = {}
    }

    for (let key in obj) {
        // 保障 key 不是原型的属性
        if (obj.hasOwnProperty(key)) {
            // 递归调用!!!result[key] = deepClone(obj[key])
        }
    }

    // 返回后果
    return result
}

class

// 类
class Student {constructor(name, number) {
        this.name = name
        this.number = number
        // this.gender = 'male'
    }
    sayHi() {
        console.log(` 姓名 ${this.name},学号 ${this.number}`
        )
        // console.log(
        //     '姓名' + this.name + ',学号' + this.number
        // )
    }
    // study() {//}
}

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

const madongmei = new Student('马冬梅', 101)
console.log(madongmei.name)
console.log(madongmei.number)
madongmei.sayHi()

继承

// 父类
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.number}`)
    }
}

// 子类
class Teacher extends People {constructor(name, major) {super(name)
        this.major = major
    }
    teach() {console.log(`${this.name} 传授 ${this.major}`)
    }
}

// 实例
const xialuo = new Student('夏洛', 100)
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()

原型关系

  • 每个 class 都有显式原型
  • 每个实例都有隐式原型_proto_
  • 实例的_proto_指向对应 class 的 prototype
  • 基于原型的执行规定

    • 获取实例对象的属性或执行办法时
    • 先在本身属性和办法寻找
    • 如果找不到则主动去隐式原型_proto_中查找

原型链

手写繁难 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) {}}

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