首页 > 其他分享 >JS实现继承的几种方式

JS实现继承的几种方式

时间:2023-03-09 23:00:00浏览次数:33  
标签:构造函数 prototype name 继承 arr 几种 实例 JS 属性

前言

JS作为面向对象的弱类型语言,继承也是其非常强大的特性之一。那么如何在JS中实现继承呢?让我们拭目以待。

预备知识

1、构造函数的属性


funcion A(name) {
  this.name = name; // 实例基本属性 (该属性,强调私有,不共享) this.arr = [1]; // 实例引⽤属性 (该属性,强调私⽤,不共享)
  this.say = function() { // 实例引⽤属性 (该属性,强调复⽤,需要共享)
    console.log('hello')
  }
}

注意:数组和⽅法都属于‘实例引⽤属性’,但是数组强调私有、不共享的。⽅法需要复⽤、共享。
在构造函数中,⼀般很少有数组形式的引⽤属性,⼤部分情况都是:基本属性 + ⽅法。

2、什么是原型对象

简单来说,每个函数都有prototype属性,它就是原型对象,通过函数实例化出来的对象有个 proto 属性,指向原型对象。

let a = new A()
a. proto == A.prototype

// prototype的结构如下
A.prototype = {
  constructor: A,
  ...其他的原型属性和⽅法
}

3、原型对象的作⽤

原型对象的⽤途是为每个实例对象存储共享的⽅法和属性,它仅仅是⼀个普通对象⽽已。并且所有的实例是共享同⼀个原型对象,因此有别于实例⽅法或属性,原型对象仅有⼀份。⽽实例有很多 份,且实例属性和⽅法是独⽴的。在构造函数中:为了属性(实例基本属性)的私有性、以及⽅法(实例引⽤属性)的复⽤、共享。我们提倡:(即下文出现的组合继承方式)

  • 将属性封装在构造函数中
  • 将⽅法定义在原型对象上
funcion A(name) {
  this.name = name; // (该属性,强调私有,不共享)
}
A.prototype.say = function() { // 定义在原型对象上的⽅法 (强调复⽤,需要共享) 
  console.log('hello')
}

// 不推荐的写法:[原因](https://blog.csdn.net/kkkkkxiaofei/article/details/46474303)
A.prototype = {
  say: function() { console.log('hello') }
}

五种js继承⽅式

原型链继承

  • 核⼼:将⽗类实例作为⼦类原型
  • 优点:⽅法复⽤
    • 由于⽅法定义在⽗类的原型上,复⽤了⽗类构造函数的⽅法。⽐如say⽅法。
  • 缺点:
    • 创建⼦类实例的时候,不能传⽗类的参数(⽐如name)。
    • ⼦类实例共享了⽗类构造函数的引⽤属性,⽐如arr属性。
    • ⽆法实现多继承。
function Parent(name) {
  this.name = name || '⽗亲'; // 实例基本属性 (该属性,强调私有,不共享) this.arr = [1]; // (该属性,强调私有)
}
Parent.prototype.say = function() { // -- 将需要复⽤、共享的⽅法定义在⽗类原型上
  console.log('hello')
}
function Child(like) { 
  this.like = like;
}

Child.prototype = new Parent() // 核⼼,但此时Child.prototype.constructor==Parent 
Child.prototype.constructor = Child // 修正constructor指向

let boy1 = new Child() 
let boy2 = new Child()

// 优点:共享了⽗类构造函数的say⽅法
console.log(boy1.say(), boy2.say(), boy1.say === boy2.say); // hello , hello , true

// 缺点1:不能向⽗类构造函数传参
console.log(boy1.name, boy2.name, boy1.name===boy2.name); // ⽗亲,⽗亲,true

// 缺点2: ⼦类实例共享了⽗类构造函数的引⽤属性,⽐如arr属性
boy1.arr.push(2);
// 修改了boy1的arr属性,boy2的arr属性,也会变化,因为两个实例的原型上(Child.prototype)有了⽗类构造函数的实例属性arr; 所以只要修改了boy1.arr,boy2.arr的属性也会变化。
console.log(boy2.arr); // [1,2]

注意1:修改boy1的name属性,是不会影响到boy2.name。因为设置boy1.name相当于在⼦类实例新增了name属性。
注意2:console.log(boy1.constructor); // Parent 你会发现实例的构造函数居然是Parent。

⽽实际上,我们希望⼦类实例的构造函数是Child,所以要记得修复构造函数指向。修复如下:Child.prototype.constructor = Child;

标签:构造函数,prototype,name,继承,arr,几种,实例,JS,属性
From: https://www.cnblogs.com/caijinghong/p/17201784.html

相关文章

  • 2023 最新 Three.js 快速入门教程 All In One
    2023最新Three.js快速入门教程AllInOneThree.js核心概念Shader着色器Render渲染器材质贴图纹理骨骼动画网格几何体模型灯光摄像机相机场景舞台......
  • ip2region 在nodejs中的使用
    ip2region在nodejs中的使用ip2regionv2.0-是一个离线IP地址定位库和IP定位数据管理框架,10微秒级别的查询效率,提供了众多主流编程语言的xdb数据生成和查询客户端实......
  • toFormData.js?9ba3:98 Uncaught (in promise) TypeError: target must be an object
    toFormData.js?9ba3:98Uncaught(inpromise)TypeError:targetmustbeanobject在做vue前端开发时,需要报错,,困扰我这个菜鸟挺久的,后来终于解决了,这里记录一下:  ......
  • js的一些设计模式概念记录
    工厂模式functioncreatePerson(name,age,job){leto=newObject();o.name=name;o.age=age;o.job=job;o.sayName=function(){console.lo......
  • JSON.parse()没反应
    https://www.runoob.com/json/json-parse.htmlhttps://blog.csdn.net/weixin_42700654/article/details/117782146JSON通常用于与服务端交换数据。在接收服务器数据时......
  • 问题记录:jss文件服务器定时任务下载失败
    jss文件服务器定时任务下载失败报错信息:客户端http连接池获取连接超时问题背景:每5min跑一次定时任务,从文件服务器下载文件更新内存,但是更新内存前会拿文件更新时间进行......
  • js字符串详解(一):什么是字符串,内置对象以及包装类型对象
    1.什么是:多个字符组成的只读字符数组   vs数组:下标i          length          slice() concat   不同:......
  • js字符串详解(二):字符串API
    所有字符串API都无权修改原字符串,只能返回新字符串!转换 1.大小写转换:将字符串中所有英文字母转为统一的大小写   何时:只要不区分大小写时,都要先转为一致的大......
  • js正则表达式详解(一):语法
    什么是:专门定义一类字符串统一规则的表达式   何时:1.按照指定规则模糊查找一类关键词时      2.表单中验证输入项的格式  如何:语法:   ......
  • js正则表达式详解(二):RegExp的Api
       验证:检查字符串是否完全符合正则表达式的要求!   如何:varbool=reg.test(待检测字符串)     强调:只要验证,reg中必须前加^后加$    ......