一、prototype的应用
 
        每一个函数都拥有一个属性 prototype
 
        给构造函数提供共有的属性和方法
 
 
        Date.prototype.format = function () {
            // this -> 实例化的这个对象,不是构造函数
            let y = this.getFullYear();
            let m = this.getMonth() + 1;
            let d = this.getDate(); 
            return y + '-' + m + '-' + d
        }
        let date = new Date();
        let res = date.format();
        console.log(res); // 2022-1-6
 
二、 原型
 
 
 
        function Dog(type) {
            this.type = type ;
            this.say = '汪'
        }
        Dog.prototype.color = 'red'
        const d = new Dog('二哈')
        console.log(d);
        console.log(d.say); // 汪
        console.log(d.color); // red 
        console.log(d.constructor); // 构造器
        console.log(d.__proto__); // 原型对象
 
三、原型对象 prototype
 
        function Person(name , age) {
            this.name = name ;
            this.age = age ;
        }
        Person.prototype.xing = '陈'
        const p = new Person('小花',16)
        // p 自己没有xing这个属性
        console.log(p.xing); //  陈
        console.log(p.hasOwnProperty('name')); // true
        // name是p自身的属性
        console.log(p.hasOwnProperty('xing')); // false
        // xing不是p自身的属性,是继承而来的
        console.log(p.constructor);
 
 四、原型链
 
 
        // 原型会指向构造函数的原型对象
        console.log(p.__proto__ == Person.prototype); // true
        // 原型对象也是一个对象, 因此也有原型,它的原型就是Object.prototype
        console.log(Person.prototype.__proto__ == Object.prototype); // true
        // Object.prototype 也是原型对象,指向null
        console.log(Object.prototype.__proto__ == null);//true 
        console.log(p.__proto__.__proto__.__proto__ == null); // true
 
        // 函数也是对象,因此函数也有原型
        console.log(Person.__proto__ == Function.prototype); // true
        //
        console.log(Function.prototype.__proto__ == Object.prototype);
        console.log(Object.prototype.__proto__ == null);
 
 五、instanceOf
 
        // Array.isArray()  // 布尔值
 
        // constructor // 可以判断数组
 
        // instanceof 用于判断一个对象是否是一个构造函数的实例化对象
 
 
 
 
六、new
 
 
        function Person(type) {
            // const obj = {}
            // this -> obj
            // obj.__proto__ = Person.prototype
            // return obj
            console.log(this);
            // 这个obj的原型是Object.prototype
        }
        
        const p = new Person()
     
        console.log(p.__proto__ == Person.prototype); // true
        const obj = {}
        console.log(obj.__proto__ == Object.prototype);// true
 
 七、原型的引用
 
      const oPs1 = document.querySelectorAll('p')
      // NodeList
      const oPs2 = document.getElementsByTagName('p')
      // HTMLCollection
      console.log(oPs1,oPs2);
      // NodeList forEach 
      // HTMLCollection 没有forEach 
      oPs1.forEach( v => {
          console.log(v);
      })
      
      const len = oPs2.length 
      oPs2.__proto__ = Array.prototype  // 强行改变了原型的指向 length 没了
      oPs2.length = len
      console.log(oPs2);
      oPs2.forEach( v => {
          console.log(v);
      })
    // oPs2.push('a')  push会改变数组