类原型重定向、函数重定向——画图讲解+试题分析

原型重定向概念 

概念:改变内置原型指向

使用场景:批量给内置原型上增加属性和方法

存在的问题:

  1. 重新定向的对象中没有constructor
  2. 原始的原型对象上,存放的属性方法,不会放到重新定向的对象上,导致实例不能再用原始的那些方法了
  3. 原始的原型对象不被占用后,会被内存释放掉
  4. 内置类的原型都不允许重定向

2 重定向陪写及问题解决

2.1 基础写法

function Func() {}
// 向原型上扩展 A B C D 四方法
Func.prototype.A = function () {};
Func.prototype.B = function () {};
Func.prototype.C = function () {};
Func.prototype.D = function () {};

let f1 = new Func;
console.log(f1);

输出结果如下,可见 f1 原型上有 A B C D 四方法,且 Func 上没有 constructor。

类原型重定向、函数重定向——画图讲解+试题分析

未重定向的函数原型上有 constructor ,如下

类原型重定向、函数重定向——画图讲解+试题分析

重定向一般用于批量添加属性和方法的场景中,若如上所写,则需要写很多 Func.prototype ,非常麻烦且不高级,优化见2.2

2.2 优化1版写法

为解决写法麻烦的问题,咱可以直接让 Func2.prototype 指向一个对象。

为解决没有 constructor 的问题,咱可以手动添加 constructor。

// 直接更改 Func.prototype 的指向
Func.prototype = {
    // 可以手动设置constructor
	constructor: Func,
	E: function () {},
	F: function () {}
};

let f2 = new Func;
console.log(f2);

输出结果如下,可见 constructor 和 E F 两方法已添加至原型,但是 2.1 中添加的 A B C D 已经被覆盖了,这样在多人合作开发中存在隐患

类原型重定向、函数重定向——画图讲解+试题分析

 2.3 优化2版写法

两个原型对象合并,用新的原型对象替换原始的原型对象【 注意:如果新老有个属性方法相同,则新的值会替换老的值 

Func.prototype = Object.assign(Func.prototype, {
	G: function () {},
	H: function () {}
});

Object.assign() 知识补充:

用于将所有可枚举属性的值从一个或多个源对象复制到目标对象。

  • 它将返回目标对象
  • 目标对象本身会改变
  • 若源对象与目标对象具有相同的属性,你们源对象的属性值会覆盖目标对象的属性值

Object.assign( target, ...sources )  // target:目标对象,sources:源对象

 输出结果如下,保留了原来的所有属性和方法,【 注意:如果新老有个属性方法相同,则新的值会替换老的值 

类原型重定向、函数重定向——画图讲解+试题分析

2.4 升级版写法

为解决新老两个属性方法同名覆盖问题。

把老的原型对象作为新原型对象的上级原型(即增长原型链)。

// 先创建一个原型指向 Func.prototype 的新对象 protoNew
let protoNew = Object.create(Func.prototype);
// 然后让新对象与 【需要批量扩展到 Func 上的扩展的方法】 合并
protoNew = Object.assign(protoNew, {
	H: function () {},
	I: function () {}
});
// 最后更改 Func.prototype 的指向
Func.prototype = protoNew;

 输出结果如下:新添加的方法都存在,且之前添加的方法存在于原型链上,可以通过原型链查找到并使用。

类原型重定向、函数重定向——画图讲解+试题分析

3 笔试题分析

分析输出结果

function fun() {
	this.a = 0
	this.b = function () {
	    alert(this.a)
	}
}
fun.prototype = {
	b: function () {
		this.a = 20
		alert(this.a)
	},
	c: function () {
		this.a = 30
		alert(this.a)
	},
}
var my_fun = new fun()
my_fun.b()
my_fun.c()

 画图讲解如下

类原型重定向、函数重定向——画图讲解+试题分析

 

上一篇:JUC之AbstractQueuedSynchronizer原理分析 - 独占/共享模式


下一篇:java 类和继承