原型链之间的关系
@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。
????????
?
@ 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;
????????}?
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!