三 原型和原型链

82 阅读1分钟

如何判断一个变量是不是数组

var arr = [];
arr instanceof Array // true
arr.constructor === Array
Object.prototype.toString.call(arr) === '[object Array]'
Array.isArray(arr) // true

知识点:class和继承,类型判断instanceof,原型和原型链

用class实现继承

class的原型本质:

组合式继承,es6的继承本质上为 原型链 + 盗用构造函数

  • 创建对象
//类
//class + 名称 模板
class Student { 
  //当前构建的实例
  constructor(name,number){
    this.name = name;
    this.number = number;
  }
  sayHi( ) {//方法
    console.log(
        `姓名 ${this.name},学号 ${this.number}`//反引号
    )
  }
}

//通过类 new 对象/实例
const xiaoluo = new Student('夏洛',100 );
console.log(xiaoluo.name); // 夏洛
console.log(this.number); // 100
xiaoluo.sayHi(); // 姓名夏洛, 学号100
  • 继承
//父类
  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 xiaoluo = new Student('夏洛',100 );
  console.log(xiaoluo.name); // 夏洛
  console.log(xiaoluo.number); // 100
  xiaoluo.sayHi(); // 姓名 夏洛 学号 100
  xiaoluo.eat(); // 夏洛 eat something
  
  const wanglaoshi = new Teacher('王老师','语文');
  console.log(wanglaoshi.name); // 王老师
  console.log(wanglaoshi.major); // 语文
  wanglaoshi.teach(); // 王老师 教授 语文
  wanglaoshi.eat(); // 王老师 eat something

image.png

class 的继承方式,包括属性和方法 extends 继承自.... super 调用父类构造函数,传递父类的值,避免一处多改

image.png

instanceof

A instanceof B 的本质:B的原型是否存在于A所在的原型链上,如果存在,返回true,否则返回false

instanceof实现原理
function instanceOf (obj,constructor){
    // 1.分别获取二者的原型
    let __proto__ = Object.getPrototypeOf(obj)
    let prototype = constructor.prototype
    // 2.无限循环沿着原型链一层一层往上查询
    while (true) {
        if (!__proto__) return false
        if (__proto__ === prototype) return true
        __proto__ = Object.getPrototypeOf(__proto__)
    }
}

console.log(instanceOf([], Object)) // true

如何理解JS原型

每个class都有显式原型 prototype 每个实例都有隐式原型 proto  实例的隐式原型指向class的显式原型

原型链的执行规则  先找自身的_proto_ 如果没有 则一直找 知道找到为止

instance of 这个办法 就是判断这个 实例有没有在原型链里面

实例的隐式原型指向类的显式原型 类的显示原型的隐式原型在指向上一层

手写jQuery插件和扩展性

  • 插件机制就是用prototype来对原型进行补充加强
  • 造轮子就是用extends继承,然后新建自己的新方法
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)
    })
  }
  // 扩展很多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'))