HarmonyOS应用实战开发-手写JS中的继承实现以及New、this、instanceof

构造函数、原型对象和实例之间的关系

详细了解JS中的原型以及原型链可见 juejin.cn/post/733711…

还是以一个简单的例子复习一下 原型和原型链
在这里插入图片描述
在这里插入图片描述

JS中的原型关系图

在这里插入图片描述

借助的几个工具

1.TS Playground 将TS转义成JS www.typescriptlang.org/play
2.Babel 将高等的JS转成低等的JS babeljs.io/repl
3.JS代码在线格式化 www.bejson.com/jshtml_form…

手写继承

原型链实现

// 父类型
function Super(){
    this.flag = 'super';
}
// 父类型原型上的方法
Super.prototype.getFlag = function(){
    return this.flag;
}

// 子类型
function Sub(){
    this.subFlag = 'sub';
}
// 实现继承。将子类的prototype设置为父类的一个实例
Sub.prototype = new Super();
// 子类型原型上的方法
Sub.prototype.getSubFlag = function(){
    return this.subFlag;
}

const instance = new Sub();

console.log(instance.subFlag); // sub
console.log(instance.flag); // super

使用这种方式实现继承,存在一些问题

一、原型对象上的属性 会被所有实例共享

在通过原型链来实现继承时,原型对象上的属性被会所有实例共享,一旦一个实例修改了原型对象的属性值,会立刻反应到其他实例上

Sub.prototype.flag = 'hahahahah';
这里修改了原型对象Sub.prototype上的flag属性后,所有实例的flag都变成了这个值

二、创建子类型的实例时,不能向父类型的构造函数传递参数

实际上,应该说是 没有办法在不影响所有对象实例的情况下,给父类型的构造函数传递参数,我们传递的参数会成为所有实例的属性

借用构造函数

基本思想:apply() 或 call() 方法,在子类型构造函数的内部调用父类型的构造函数,使得子类型拥有父类型的属性和方法

// 父类型 构造函数,可以传递参数
function Super(properties){
  this.properties = [].concat(properties);
  this.colors = ['red', 'blue', 'green'];
}

function Sub(properties){
  // 继承了 Super,传递参数,互不影响
  Super.apply(this, properties);
}

var instance1 = new Sub(['instance1']);
instance1.colors.push('black');
console.log(instance1.colors); // 'red, blue, green, black'
console.log(instance1.properties[0]); // 'instance1'

var instance2 = new Sub();
console.log(instance2.colors); // 'red, blue, green'
console.log(instance2.properties[0]); // 'undefined'

1.借用构造函数解决了上面提到的两个问题:现在 实例间不会共享属性了,也可以向父类型传递参数了
2.但是这种方法仍然存在一些问题:子类型无法继承父类型原型中的属性。我们只是在子类型的构造函数中调用了父类型的构造函数,没有做其他的,子类型和父类型的原型也就没有任何联系

组合继承

基本思想:使用原型链实现对原型属性和方法的继承,借用构造函数来实现对实例属性的继承。
这样,既通过在原型上定义方法实现了函数复用,又能够保证每个实例都有它自己的属性,从而发挥二者之长

function Super(properties){
  this.properties = [].concat(properties);
  this.colors = ['red', 'blue', 'green'];
}

Super.prototype.log = function() {
  console.log(this.properties[0]);
}

function Sub(properties){
  // 继承了 Super,传递参数,互不影响
  Super.apply(this, properties);
}
// 继承了父类型的原型
Sub.prototype = new Super();
// isPrototypeOf() 和 instance 能正常使用
Sub.prototype.constructor = Sub;

var instance1 = new Sub(['instance1']);
instance1.colors.push('black');
console.log(instance1.colors); // 'red,blue,green,black'
instance1.log(); // 'instance1'

var instance2 = new Sub();
console.log(instance2.colors); // 'red,blue,green'
instance2.log(); // 'undefined'

组合继承看起来很不错,但是也有它的缺点:无论什么情况下,组合继承都会调用两次父类型的构造函数:一次是在创建子类型原型的时候,另一次是在子类型构造函数内部

寄生组合式继承

基本思想:不必为了指定子类型的原型而调用父类型的构造函数,我们所需要的无非就是父类型原型的一个副本而已
通过借用构造函数来继承属性,通过借用临时构造函数来继承原型

// 用于继承的函数
function inheritPrototype(child, parent) {
  var F = function () {}
  F.prototype = parent.prototype;
  child.prototype = new F();
  child.prototype.constructor = child;
}
// 父类型
function Su
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值