关于Middle的问题

来源:5-9 【TS继承准备】寄生组合继承实现方式【最佳继承模式】-1

慕姐0416137

2021-10-09

老师我有一点不明白,既然middle是为了连接 ChinesePeople.prototype 与 People.prototype,People.call(this)已经访问了People构造函数里面的属性,那么直接使用 ChinesePeople.prototype.__ proto __ = People.prototype去访问People原型上的方法可以么?为什么还要new People呢?

写回答

2回答

keviny79

2021-10-09

 尽管两种方法都能达到目的,但使用__proto__来改变带来不好的问题!

1. 原因1:修改原型或对象的原型链属性__proto__(就是[[Prototype]])是一个不好的编码习惯

   它改变了原型链的链级指向关系,破坏了原型链的稳定性,导致原型链上依赖的方法和属性都会受到影响

  本例中的影响小一点,但依然存在影响,  影响如下:

    我们并不希望S100行创建的son对象变量在S102处能调用 Parent.prototype 上的方法,因为它是我们 S101 行 改变指向之前发生的代码  这就是修改__proto__代码代码的问题!

let son = new Son("爱好篮球", "男");// S100

Son.prototype.__proto__ = Parent.prototype// S101

Son.prototype.constructor = Son;// 让Son类的对象或函数原型.prototype指向的原型对象空间【new Parent()对象空间】有一个constructor属性

console.log("Son.prototype来看看:", Son.prototype);


console.log("abc..哦哦");

son.eat();// S102 调用 Parent原型上eat()方法成功



0
1
慕姐0416137
非常感谢!
2021-10-10
共1条回复

keviny79

2021-10-09

 原因2:修改__proto__还可能带来性能上的损耗(本例不存在这个问题)

   这个问题涉及到V8引擎方面的问题了,答案很长(给别的同学解答过,直接复制过来,你可以了解下即可 )

 

V8 引擎对于方法被调用(传入相同类型的参数)多次时 或 对象中的属性或方法多次被调用时,会使用 JIT 将函数编译成二进制代码【热编译】,以后再执行传入相同类型的参数的方法或对象中的属性或方法时,就直接执行,无需重复解释代码从而提高效率
  本质上就是把代码转换成静态类型固定不变,并且生成一个类模板来记录属性或方法中各个变量的偏移量【就通过类模板来确定位置,关于类模板可以理解执行某个方法或对象属性中的属性或者方法时V8生成的一个记录某段执行代码中变量或方法的位置【偏移量】,以后在执行相同方法或访问对象中的相同方法或属性时可以直接从这个位置查找,从而提高效率。
  
但如果这时对象中 比如prototype原型对象空间的属性或方法被 __proto__属性给修改了,那么会导致V8引擎 所以的类模板记录下的偏移量要重新计算了,但很显然就把本来高效率执行的 固定不变的JIT编译好的静态类型重新退化成了动态类型【这就是所谓的字典模式】  并且需要再度多次执行,才会再次被 JIT 将函数编译成新的二进制代码,从而营销效率

  说__proto__来修改属性影响性能,其实很容易误导大家, 因为运行时 任何数据的变化都会影响 JIT已经生成的变量的静态偏移量失效,比如方法参数类型的改变,对象属性中的值改变, 只是说__proto__它指向的是原型对象对象空间,而原型上的方法又是高频使用,所以如果我们多次使用原型空间上某个方法,比如show方法,JIT会将这个方法编译成二进制代码,固定成静态类型,并这时突然使用对象实例.__proto__修改了原型空间上的show方法的指向空间或删除了其中原型上的某个属性,刚才静态类型又退化成了动态类型。

  但是我们发现 TS继承 JS继承 依然使用了 Son.__proto__=Parent 类似的写法 ,这样写也没有问题,而更多的要避免的是 对象实例变量.__proto__的使用,因为对象可以有很多,并且它修改的是高频使用的原型对象空间,也就是对象.__proto__会对静态化的”别人“ 造成影响,但 Son.__proto__=Parent 就不用担心,因为我们 Son.__proto__=Parent  目的是让Son来访问Parent类中的静态属性或静态方法,而且仅此用而已,自写自用。


0
0

晋级TypeScript高手,成为抢手的前端开发人才

轻松驾驭 TypeScript 高级用法, 突破前端成长瓶颈

871 学习 · 425 问题

查看课程