guqzhou guqzhou
首页
快捷导航
下载站
  • Html 篇
  • Javascript 基础篇
  • 框架

    • Vue2
  • 前端文章

    • Css 篇
    • 微信开发
    • JavaScript
    • Vue
  • 学习笔记

    • 《JavaScript教程》笔记
    • 《ES6 教程》笔记
    • 《Vue》笔记
    • 《TypeScript 从零实现 axios》
    • 小程序笔记
    • JavaScript 基础
  • HTML
  • CSS
  • 技术文档
  • GitHub技巧
  • Nodejs
  • 博客搭建
  • 面试题库

    • HTML
    • CSS
    • jQuery
    • Vue
    • 零碎
  • 面试心得

    • 杂言碎语
  • 摘抄收录

    • ☆ 励志鸡汤
    • ❀ 人间烟火
    • ☣ 万物沦丧
    • ✌ 关掉烦恼
    • ✲ 小酒馆
  • 读书笔记

    • 《小狗钱钱》
    • 《穷爸爸富爸爸》
    • 《聪明人使用方格笔记本》
关于
  • 学习
  • 面试
  • 心情杂货
  • 友情链接
  • 分类
  • 标签
  • 归档
  • 网站
  • 资源
  • Vue资源
  • 主站CDN
  • Vercel
  • Netlify
  • Github
GitHub

guqzhou

喜欢所以去追求!
首页
快捷导航
下载站
  • Html 篇
  • Javascript 基础篇
  • 框架

    • Vue2
  • 前端文章

    • Css 篇
    • 微信开发
    • JavaScript
    • Vue
  • 学习笔记

    • 《JavaScript教程》笔记
    • 《ES6 教程》笔记
    • 《Vue》笔记
    • 《TypeScript 从零实现 axios》
    • 小程序笔记
    • JavaScript 基础
  • HTML
  • CSS
  • 技术文档
  • GitHub技巧
  • Nodejs
  • 博客搭建
  • 面试题库

    • HTML
    • CSS
    • jQuery
    • Vue
    • 零碎
  • 面试心得

    • 杂言碎语
  • 摘抄收录

    • ☆ 励志鸡汤
    • ❀ 人间烟火
    • ☣ 万物沦丧
    • ✌ 关掉烦恼
    • ✲ 小酒馆
  • 读书笔记

    • 《小狗钱钱》
    • 《穷爸爸富爸爸》
    • 《聪明人使用方格笔记本》
关于
  • 学习
  • 面试
  • 心情杂货
  • 友情链接
  • 分类
  • 标签
  • 归档
  • 网站
  • 资源
  • Vue资源
  • 主站CDN
  • Vercel
  • Netlify
  • Github
GitHub
  • vue2
  • CSS

  • Javascript基础

    • js介绍
    • 数据类型
    • js检查数据类型的方法
    • 内存泄漏
    • 说一下闭包,并且有什么特点
    • 页面加载和滚动事件
    • 闭包
    • DOM
    • 重绘和回流
    • 原型、原型链和继承
      • 原型
        • 概述
        • 作用
      • 原型链
      • 继承
        • 原型链继承
        • 构造函数继承
        • 组合继承
        • 寄生组合继承
        • class类继承
  • javascript进阶

  • typeScipt

  • vue2

  • vue3

  • react

  • vue实战

  • pinia的使用

  • gis

  • 前端文章

  • JavaScript文章

  • Vue文章

  • 小程序开发文章

  • uni-app

  • 学习笔记

  • TaroUI的使用

  • 工具使用

  • 前端
  • Javascript基础
guqzhou
2022-01-28
0

原型、原型链和继承

# 原型

# 概述

每一个函数都有一个prototype属性,称之为为原型;因为这个属性值是一个对象称之为原型对象

# 作用

  1. 存放属性和方法 上代码:
// 创建对象实例
const arr = new Array(1,3,5)

// 我们在构造函数上挂载一个方法
Array.prototype.map = function () {
}
// 实例对象又有个__proto__属性指向prototype原型对象
arr.__proto__ = Array.prototype  // 等价的

arr.map() // 我们就能使用构造函数上的方法

1
2
3
4
5
6
7
8
9
10
11

image-20230128111050815

分析:
构造函数Array有个属性prototype指向原型对象,比如我们挂载一个map方法;而构造函数又指向实例对象,恰好实例对象上又有个属性__proto___, arr.proto = Array.prototype ,构造函数的方法可以在实例对象上使用

# 原型链

# 继承

# 原型链继承

上代码:

function Father() {
    this.name  = 'll'
    this.age = 34
    this.obj = {
        num: 33
    }
    this.play = function(){
        console.log(this.name)
    }
}
Father.prototype.say = function () {
    console.log('会唱歌')
}
function Son() {
    // Father.call(this)  // 构造函数call方法继承
}
Son.prototype = new Father()
const ldh1 = new Son()
    ldh1.name = 'lisi'
    ldh1.obj.num = 66
    console.log(ldh1.name) //lisi
    console.log(ldh1.obj) // {num: 66}
    ldh1.play() // lisi
    ldh1.say() // 会唱歌

    console.log('-----------')

const ldh2 = new Son()
    console.log(ldh2.name) // ll
    console.log(ldh2.obj) // {num: 66}
    ldh2.play() // ll
    ldh2.say() // 会唱歌
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32

优点:
共享父类属性和方法

缺点:
1.父类所有的引用类型数据都会被子类共享,更改一个子类的数据其他数据也会跟着一起变化
2.子类实例不能给父类构造函数传参

# 构造函数继承

上代码:

function Father() {
    this.name  = 'll'
    this.age = 34
    this.obj = {
        num: 33
    }
    this.play = function(){
        console.log(this.name)
    }
}
Father.prototype.say = function () {
    console.log('会唱歌')
}
function Son() {
    Father.call(this)  // 构造函数call方法继承
}
// Son.prototype = new Father()
const ldh1 = new Son()
    ldh1.name = 'lisi'
    ldh1.obj.num = 66
    console.log(ldh1.name) //lisi
    console.log(ldh1.obj) // {num: 66}
    ldh1.play() // lisi
    ldh1.say() // ldh1.say is not a function

console.log('-----------')

const ldh2 = new Son()
    console.log(ldh2.name) // ll
    console.log(ldh2.obj) // {num: 66}
    ldh2.play() // ll
    ldh2.say() // ldh2.say is not a function
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32

优点:
父类的引用类型的数据不会被子类共享,不会互相影响

缺点:
子类不能访问父类原型属性上的方法

# 组合继承

上代码:

function Father() {
    this.name  = 'll'
    this.age = 34
    this.obj = {
        num: 33
    }
    this.play = function(){
        console.log(this.name)
    }
}
Father.prototype.say = function () {
    console.log('会唱歌')
}
function Son() {
    Father.call(this)  // 构造函数call方法继承
}
Son.prototype = new Father()
const ldh1 = new Son()
    ldh1.name = 'lisi'
    ldh1.obj.num = 66
    console.log(ldh1.name) //lisi
    console.log(ldh1.obj) // {num: 66}
    ldh1.play() // lisi
    ldh1.say() // 会唱歌

    console.log('-----------')

const ldh2 = new Son()
    console.log(ldh2.name) // ll
    console.log(ldh2.obj) // {num: 66}
    ldh2.play() // ll
    ldh2.say() // 会唱歌
    console.log(ldh2) // 打印下图
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33

image-20230128234902941

优点:
1.父类可以共用
2.父类引用类型的数据不会共享

缺点:
会调用两次父类构造函数,会有两份一样的属性和方法,影响性能

# 寄生组合继承

上代码:

function Father() {
    this.name  = 'll'
    this.age = 34
    this.obj = {
        num: 33
    }
    this.play = function(){
        console.log(this.name)
    }
}
Father.prototype.say = function () {
    console.log('会唱歌')
}
function Son() {
    Father.call(this)  // 构造函数call方法继承
}

// 中间做了一个中转
const Fn = function() {}
// 把父类的原型直接赋到新的构造函数原型
Fn.prototype = Father.prototype
// 然后让子类原型指向空的实例对象
Son.prototype = new Fn()
// 别忘了这一步
Son.prototype.constructor = Son

const ldh1 = new Son()
    ldh1.name = 'lisi'
    ldh1.obj.num = 66
    console.log(ldh1.name) //lisi
    console.log(ldh1.obj) // {num: 66}
    ldh1.play() // lisi
    ldh1.say() // 会唱歌

    console.log('-----------')

const ldh2 = new Son()
    console.log(ldh2.name) // ll
    console.log(ldh2.obj) // {num: 66}
    ldh2.play() // ll
    ldh2.say() // 会唱歌
    console.log(ldh2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42

说明:ES5最优继承,中间做了一个中转,我们创建一个空的构造函数,把父类的原型直接赋到新的构造函数原型,然后让子类原型指向空的实例对象

# class类继承

上代码:

class Father {
    constructor() {
        this.name  = 'll'
        this.age = 34
        this.obj = {
            num: 33
        }
        this.play = function(){
            console.log(this.name)
        }
    }
    say = function () {
        console.log('会唱歌')
    }
}

class Son extends Father {}

const ldh1 = new Son()
    ldh1.name = 'lisi'
    ldh1.obj.num = 66
    console.log(ldh1.name) //lisi
    console.log(ldh1.obj) // {num: 66}
    ldh1.play() // lisi
    ldh1.say() // 会唱歌

console.log('-----------')

const ldh2 = new Son()
    console.log(ldh2.name) // ll
    console.log(ldh2.obj) // {num: 66}
    ldh2.play() // ll
    ldh2.say() // 会唱歌
    console.log(ldh2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34

说明:最优继承

上次更新: 2023/01/29, 11:01:00
重绘和回流
作用域&&结构&&箭头函数

← 重绘和回流 作用域&&结构&&箭头函数 →

最近更新
01
面向对象
01-05
02
typescript用localStorage封装过期时间
01-05
03
npm、pnpm、yarn删除文件缓存
12-14
更多文章>
Theme by Vdoing | Copyright © 2021-2024 guqzhou | 萌ICP备20238188号
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式