原型链之间的关系

@1 首先我们先了解下原型链的基础知识。
        function Fn(x,y) {this.x=x; this.y =y; this.say=()=>{console.log(this.x)}} 
        let res = Fn(10,20) // 普通函数执行 因为函数体内部没有返回值所以普通函数执行得不到返回
        的结果。
        let f1 = new Fn(10,20) // 这是构造函数执行
        let f2 = new Fn(10,20) // 这是创造另外一个类的实例对象
        console.log(f1.sum) // 因为不存在所以结果是undefiend
        console.log(f1.say) // 得到的结果是10 
        console.log(f1.say===f2.say) // false  创建的两个实例对象是不相同的
@2 普通函数与构造函数的区别;
        构造函数执行也像普通函数执行一样产生私有的上下文(作用域 初始this 代码执行)
        构造函数在执行的时候会创建出一个空实例对象, 让上下文中的this执行创建的实例对象,观
        察函数的返回值,如果返回值的原始值类型或者没有返回值则把创建的实例对象返回,只有
        自己手动返回对象类型值,才以自己返回的为主。
@3  构造函数的特点:
       1. 构造函数原型对象中有一个constructor(构造器)返回值是当前构造函数本身
        Fn.prototype.constructor === Fn;
        2. 不具备prototype的函数, 箭头函数 
        3. 每一个对象数据类型的值都具备一个属性 __proto__, 属性值 指向自己所属原型Prototype
        4. 对象数据类型值、普通对象 特殊对象:数组 正则 日期 Math Error,函数对象,以及构造函
        数的prototype也属于对象数据类型。

  @4 案例展示:
         function Fn(){
                this.x = 100
                this.y = 200
                this.getX = function (){ console.log(this.x)}
        }
        Fn.prototype.getX= function (){console.log(this.x)}
        Fn.prototype.getY = function(){console.log(this.Y)}
        let f1 = new Fn;
        let f2 = new Fn;
        console.log(f1.getX===f2.getX) // false 每次new创建的实例对象是互不相关的
        console.log(f1.getY===f2.getY)// true 两个实例对象自身都没有getY这个方法找的都是原型的
        console.log(f1.__proto__.getY===fn.prototype.getY)// true f1.__proto__等于Fn.prototype
        console.log(f1.__proto__.getX===f2.getX) // false F1找的是原型上面的方法f2找的是自身的
        console.log(f1.getX===Fn.prototype.getX)// false 自身与原型的方法不相等
        console.log(f1.constoructor) //Fn 相当于f1.__proto__.constructor 
        console.log(Fn.prototype.__proto__.constorctor)// Object 相当于object.prototype.constructor
        f1.getX() // 100
        f1.__proto__.getX() // undefiend  Fn.prototype的this执行Fn.prototype 但这个this上面没有x
        f2.getY() // 200
        Fn.prototype.getY() // undefiend Fn.prototype的this指向Fn.prototype 但这个this上面没有y
@ 5 原型链之间的关系:
        1 每一个构造函数function Fn(){} 通过new都可以得到一个实例对象f1 = new Fn();
        2 每个实例对象的__proto__都指向其构造函数的prototype 也就是f1.__proto__ ===
           Fn.prototype;
        3 每一个构造函数的prototype本身也是一个对象数据类型,也有__proto__属性,所以指向更
           高一级的Object.prototype;
        4  Object.prototype也是属于对象数据类型也有__proto__属性,但是object.prototype的
           __peoto__指向了null。
        

原型链之间的关系_第1张图片 

@ 6 封装new实例对象的函数:
        function _new(ctor,...params) {
                let obj1 = {} // 创建一个空的对象
                obj1.__proto__ = ctor.prototype // 让对象的__proto__属性指向于构造函数的prototype
                const result = ctor.call(obj1,...params) //  改变this指向
                if(result !== null  && /^(object | function)$/.test(typeof result))  return result; // 如果这个
                函数返回的是原始值类型 则把实例返回 
                return obj;
        } 
        let sammao = _new(Dog,'三毛');
        严格判断:
        function _new(ctor,...params) {
                let obj1 = {} // 创建一个空的对象
                if(!ctor.prototype || ctor===Symbol || ctor===BigInt) throw new Error(...) // 抛出错误
                obj = Object.create(ctor.prototype) // 把ctor的原型挂载在obj原型上面
                obj1.__proto__ = ctor.prototype // 让对象的__proto__属性指向于构造函数的prototype
                const result = ctor.call(obj1,...params) //  改变this指向
                if(result !== null  && /^(object | function)$/.test(typeof result))  return result; // 如果这个
                函数返回的是原始值类型 则把实例返回 
                return obj;
        } 

你可能感兴趣的:(javascript,前端,开发语言)