原型与原型链【面试回顾】

深拷贝

/** * 深拷贝 * @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'))

    推荐阅读