Jacky's blog Jacky's blog
首页
  • 编码专题
  • 深入浅出 Vite
  • 深入浅出 babel
  • 快速上手API
  • 深入浅出 react
  • Node

    • code-notebook
  • 状态管理

    • redux
  • 前端工程化

    • Wepack
  • React源码

    • React源码
  • 组件库封装

    • 组件库
  • 开发工具

    • Vscode 插件
  • 项目展示
  • 案例中心 (opens new window)
  • First Project
  • 基础算法题
  • 链表题
  • 动态规划
  • 双指针
  • 递归
  • 数据结构
  • 前端学习计划 (opens new window)
  • 技术随笔
  • 转载文章
  • 包管理工具
  • 前端学习周报
  • VSCode插件
  • Promise 专题
  • 函数技巧
  • React 专题
  • 配置文件

    • TSCONFIG-配置 (opens new window)
    • NGINX-配置 (opens new window)
    • 正则规则查询手册 (opens new window)
    • Lint 配置 (opens new window)
  • 教程

    • GIT-教程
    • NPM SCRIPTS-工作流 (opens new window)
    • DOCKER-教程 (opens new window)
    • LERNA-教程 (opens new window)
    • GIT-常用操作整理 (opens new window)
  • VSCode

    • LAUNCH.JSON (opens new window)
  • 指令

    • NPM 指令 (opens new window)
    • NVM 指令 (opens new window)
    • Nginx 指令 (opens new window)
    • YARN 指令 (opens new window)
    • PNPM 指令 (opens new window)
  • 库

    • FS-EXTRA 库 (opens new window)
    • NODE 库-PATH (opens new window)
  • 永远的神

    • 魔法师卡颂-自顶向下学 React 源码 (opens new window)
    • 全栈潇晨 (opens new window)
    • 博客-程序员山月-Daily (opens new window)
    • 淘系前端:冴羽 (opens new window)
  • 系列文章

    • 《图解HTTP》 (opens new window)
    • 《ES6标准入门》 (opens new window)
    • 《现代JavaScript教程》 (opens new window)
    • 《深入浅出Webpack》 (opens new window)
    • VSCode 插件系列:小茗同学 (opens new window)
    • JEST 教程 (opens new window)
    • 前端精读周刊:各种精读系列 (opens new window)
    • 一文吃透系列 (opens new window)
    • 图解 REACT 原理 (opens new window)
  • 实用网站

    • MDN (opens new window)
    • CAN I USE (opens new window)
    • TYPESCRIPT-ESLint-RULES (opens new window)
    • ESLint-RULES (opens new window)
    • FRONT-END TREND (opens new window)
    • NPM TREND (opens new window)
    • 在线分析 Node 依赖 (opens new window)
    • FIND NPM (opens new window)
    • CODE PEN (opens new window)
    • 印记中文 (opens new window)
    • TOOL.LU (opens new window)
    • 阮一峰-网道 (opens new window)
    • DIGITAL OCEAN (opens new window)
    • DEVDOCS.IO (opens new window)
    • JOI (opens new window)
  • 算法

    • 小浩算法 (opens new window)
    • LABULADONG 的算法小抄 (opens new window)
    • 力扣 SOLUTION (opens new window)
    • HACKER RANK (opens new window)
    • 代码随想录 (opens new window)
  • 博客系列

    • 美团大佬 (opens new window)
    • 蜡笔小伟 (opens new window)
    • 优秀博客1 (opens new window)
    • 优秀博客2-umi (opens new window)
    • 优质博客 (opens new window)
  • CSS

    • CSS-EASING 库 (opens new window)
    • ROUGH.JS (opens new window)
    • CSS 网站收集
    • UNOCSS (opens new window)
  • 前端

    • PROMISE (opens new window)
    • UNDERSCORE.JS (opens new window)
    • study with BGM (opens new window)
    • nginx【B站视频】 (opens new window)
    • 机器学习
    • Js基础
  • 掘金已购课程

    • 前端自动化测试精讲 (opens new window)
    • 深入浅出 Vite (opens new window)
    • 现代 Web 布局 (opens new window)
    • 前端算法与数据结构 (opens new window)
    • 基于 Vite 的 SSG 框架开发实战 (opens new window)
    • SSR 实战:官网开发指南 (opens new window)
    • WebGL 入门与实践 (opens new window)
    • 玩转 CSS 的艺术之美 (opens new window)
    • 前端调试通关秘籍 (opens new window)
    • React 进阶实践指南 (opens new window)
    • TypeScript 全面进阶指南 (opens new window)
    • 前端缓存技术与方案解析 (opens new window)
    • npm scripts 前端工作流 (opens new window)
    • Webpack5 核心原理与应用实践 (opens new window)
  • 购物车

    • 张鑫旭-技术写作指南 (opens new window)
    • 深入剖析 Node.js 底层原理 (opens new window)
    • 前端开发者的现代 C++ 课 (opens new window)
    • 从前端到全栈 (opens new window)
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

Jacky Wang

行到水穷处,坐看云起时
首页
  • 编码专题
  • 深入浅出 Vite
  • 深入浅出 babel
  • 快速上手API
  • 深入浅出 react
  • Node

    • code-notebook
  • 状态管理

    • redux
  • 前端工程化

    • Wepack
  • React源码

    • React源码
  • 组件库封装

    • 组件库
  • 开发工具

    • Vscode 插件
  • 项目展示
  • 案例中心 (opens new window)
  • First Project
  • 基础算法题
  • 链表题
  • 动态规划
  • 双指针
  • 递归
  • 数据结构
  • 前端学习计划 (opens new window)
  • 技术随笔
  • 转载文章
  • 包管理工具
  • 前端学习周报
  • VSCode插件
  • Promise 专题
  • 函数技巧
  • React 专题
  • 配置文件

    • TSCONFIG-配置 (opens new window)
    • NGINX-配置 (opens new window)
    • 正则规则查询手册 (opens new window)
    • Lint 配置 (opens new window)
  • 教程

    • GIT-教程
    • NPM SCRIPTS-工作流 (opens new window)
    • DOCKER-教程 (opens new window)
    • LERNA-教程 (opens new window)
    • GIT-常用操作整理 (opens new window)
  • VSCode

    • LAUNCH.JSON (opens new window)
  • 指令

    • NPM 指令 (opens new window)
    • NVM 指令 (opens new window)
    • Nginx 指令 (opens new window)
    • YARN 指令 (opens new window)
    • PNPM 指令 (opens new window)
  • 库

    • FS-EXTRA 库 (opens new window)
    • NODE 库-PATH (opens new window)
  • 永远的神

    • 魔法师卡颂-自顶向下学 React 源码 (opens new window)
    • 全栈潇晨 (opens new window)
    • 博客-程序员山月-Daily (opens new window)
    • 淘系前端:冴羽 (opens new window)
  • 系列文章

    • 《图解HTTP》 (opens new window)
    • 《ES6标准入门》 (opens new window)
    • 《现代JavaScript教程》 (opens new window)
    • 《深入浅出Webpack》 (opens new window)
    • VSCode 插件系列:小茗同学 (opens new window)
    • JEST 教程 (opens new window)
    • 前端精读周刊:各种精读系列 (opens new window)
    • 一文吃透系列 (opens new window)
    • 图解 REACT 原理 (opens new window)
  • 实用网站

    • MDN (opens new window)
    • CAN I USE (opens new window)
    • TYPESCRIPT-ESLint-RULES (opens new window)
    • ESLint-RULES (opens new window)
    • FRONT-END TREND (opens new window)
    • NPM TREND (opens new window)
    • 在线分析 Node 依赖 (opens new window)
    • FIND NPM (opens new window)
    • CODE PEN (opens new window)
    • 印记中文 (opens new window)
    • TOOL.LU (opens new window)
    • 阮一峰-网道 (opens new window)
    • DIGITAL OCEAN (opens new window)
    • DEVDOCS.IO (opens new window)
    • JOI (opens new window)
  • 算法

    • 小浩算法 (opens new window)
    • LABULADONG 的算法小抄 (opens new window)
    • 力扣 SOLUTION (opens new window)
    • HACKER RANK (opens new window)
    • 代码随想录 (opens new window)
  • 博客系列

    • 美团大佬 (opens new window)
    • 蜡笔小伟 (opens new window)
    • 优秀博客1 (opens new window)
    • 优秀博客2-umi (opens new window)
    • 优质博客 (opens new window)
  • CSS

    • CSS-EASING 库 (opens new window)
    • ROUGH.JS (opens new window)
    • CSS 网站收集
    • UNOCSS (opens new window)
  • 前端

    • PROMISE (opens new window)
    • UNDERSCORE.JS (opens new window)
    • study with BGM (opens new window)
    • nginx【B站视频】 (opens new window)
    • 机器学习
    • Js基础
  • 掘金已购课程

    • 前端自动化测试精讲 (opens new window)
    • 深入浅出 Vite (opens new window)
    • 现代 Web 布局 (opens new window)
    • 前端算法与数据结构 (opens new window)
    • 基于 Vite 的 SSG 框架开发实战 (opens new window)
    • SSR 实战:官网开发指南 (opens new window)
    • WebGL 入门与实践 (opens new window)
    • 玩转 CSS 的艺术之美 (opens new window)
    • 前端调试通关秘籍 (opens new window)
    • React 进阶实践指南 (opens new window)
    • TypeScript 全面进阶指南 (opens new window)
    • 前端缓存技术与方案解析 (opens new window)
    • npm scripts 前端工作流 (opens new window)
    • Webpack5 核心原理与应用实践 (opens new window)
  • 购物车

    • 张鑫旭-技术写作指南 (opens new window)
    • 深入剖析 Node.js 底层原理 (opens new window)
    • 前端开发者的现代 C++ 课 (opens new window)
    • 从前端到全栈 (opens new window)
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • 常用资源导航
  • 概念
  • 代码格式化
  • 面向对象基础
  • 构造函数与原型
    • 2.继承
      • 2.1 call()
      • 2.2 属性继承:修改this指针后执行父函数
      • 2.3 方法继承
  • 函数进阶
  • 函数柯里化
  • 函数-传参
  • axios
  • Node 和 ES6 模块系统
  • JS
wangjiasheng
2021-01-08
目录

构造函数与原型

# 1.1 概述

在经典的OOP语言中,如Java,C++均存在class的概念,class是object的模板,而object是class的对象,但在ES6以前,JS中并无class的概念。

目前浏览器的JavaScript是ES5版本居多,大多数高级浏览器支持ES6,但也只支持了基本的特性和功能。而在ES6之前,object的实现不是基于class实现的,而是以一种称为构造函数的特殊函数实现的。

对象的创建:

//1.直接用{}实现【对象字面量】---直接使用
var obj1 = {};
//2.使用new方法 + Object对象---直接调用
var obj2 = new Object(); 
//3.使用new + 构造函数(特殊函数)---构造时
function Star(name,age){
    this.name = name;
    this.age = age;
    this.sing = function(){
        console.log('我会唱歌');
    }
}
var obj3 = new Star("刘德华",45);
obj3.sing();
1
2
3
4
5
6
7
8
9
10
11
12
13
14

⚠️说明:

  • 第一条,说明对象的本质就是一对花括号{},我们可以完成对其幅值属性的操作。如obj1.属性名="str"

  • 第二条,说明对象存在一个老祖宗Object,例如我们常用的数组创建,我们使用的Array是基于Object类通过构造函数魔改而来的,其内置了很多对矩阵的操作,如reverse()等。

    var arr1 = new Array.(20,10,3); // object创建,方式二
    var arr2 = [20,10,3] ; // 字面量创建,方式一
    // 可直接调动内置方法
    console.log(arr1.reverse());
    
    1
    2
    3
    4

# 1.2 构造函数

构造函数是一种特殊的函数,主要用来的初始化对象,我们常把对象中的一些公共的属性和方法抽取出来,并进行封装。

object的生成过程:new + 构造函数

  1. 内存中先开辟一块新的空间

  2. this指向这个空间内存

  3. 执行构造函数内的内容

    ⚠️注意:这里并不是简单的copy[copy有可能只能copy到存放对象的索引],而是执行一遍伪"类"(构造函数)则不同,其可以完全拷贝"类"中的一切。

  4. return该函数,但是构造函数比较特殊,不需要写return关键字

成员的添加:

JavaScript 的构造函数中可以添加一些成员,可以在构造函数本身上添加,也可以在构造函数内部的 this 上添加。通过这两种方式添加的成员,就分别称为静态成员和实例成员。

  • 静态成员:在构造函数本上添加的成员称为静态成员,只能由构造函数本身来访问
  • 实例成员:在构造函数内部创建的对象成员称为实例成员,只能由实例化的对象来访问

# 1.3 内存爆炸

构造函数,会给每个object开一个新地址去存function,而这个不同object中的functoin是相同的,这样使用内存空间和时间开销都很大。

解决思路:在构造函数定义的时候,就预先设置一个公共的空间存放公有的方法【共享方法】,此方法就称之为原型。

# 1.4 原型 prototype

⚠️有几个点需要注意:

  • 构造函数(constructor)通过prototype属性访问公共区域【原型对象】。

  • 对象(object)通过__prototype__属性访问公共区域【原型对象】。

    两者都是使用constructor关键字返回上级构造函数

构造函数对象、实例对象、原型对象三者转化

原型对象也存在prototype[原型对象],而该原型也存在constructor函数,直到最初始的原型对象是Object原型对象。

⚠️注意:原型对象里头存放的是方法,而原型中的this指向的是这个方法的调用者,即实例对象。

# 1.5 扩展案例

通过一个案例来说明,对内置的对象(如Array)进行扩展sum功能。

如果忘记JavaScript中存在的方法,可以直接查看Array的原型就可以看到内置方法(console.log(Array.prototype))

Demo:Array中未定义求和的功能

<script type="text/javascript">
Array.prototype.sum = function() {
    var sum = 0;
    for (let i = 0; i < this.length; i++) {
        sum += this[i];
    }
    return sum;
}
let array = [1, 2, 3];
console.log(array.sum());
console.log(Array.prototype);
</script>
1
2
3
4
5
6
7
8
9
10
11
12

查看自定义的方法:内置的都是浅色的,自定义以深色显示。

image-20210109131359041

# 2.继承

ES6之前并没有给我们提供 extends 继承。我们可以通过构造函数+原型对象模拟实现继承,被称为组合继承。

# 2.1 call()

function fun(){...}
// 正常调用function,直接加()就可以了
fun(); 
// 修改this指针
fun.call(修改this的指向)
1
2
3
4
5

# 2.2 属性继承:修改this指针后执行父函数

function Father(name,age){
    this.name = name;
    this.age = age;
}
function Son(name,age,score){
    Father.call(this,name,age,sex); // 在ES6中,使用super()重新执行一遍父类的constructor对象
    this.score = score;
}
1
2
3
4
5
6
7
8

# 2.3 方法继承

基本操作:

子类.prototype = new 父类();
子类.prototype.constructor = 子类;
1
2

⚠️说明:new相当于新开内存,可以将子类的原型也给完整拷贝一份。

点击查看

Demo案例:

function Father(name, age) {
    this.name = name;
    this.age = age;
}
// 在外部定义原型
Father.prototype.fatherMethod = function() {
    console.log("父类的方法");
}

function Son(name, age, score) {
    Father.call(this, name, age); // 在ES6中,使用super()重新执行一遍父类的constructor对象
    this.score = score;
}
// 在外部定义原型
Son.prototype = new Father();
Son.prototype.constructor = Son; // 注意:需要改上一层的指向
Son.prototype.sonMethod = function() {
    console.log("子类的方法");
}

let father = new Father('刘德华', 46);
let son = new Son('刘德华', 46, 100);

console.log(father);
console.log(son);
son.fatherMethod();
son.sonMethod();
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
编辑 (opens new window)
上次更新: 2022/04/06, 15:04:00
面向对象基础
函数进阶

← 面向对象基础 函数进阶→

最近更新
01
如何理解浏览器的 user agent 用户代理的含义?
11-05
02
浏览器事件循环机制
10-31
03
浏览器页面渲染机制【2023】
10-15
更多文章>
Theme by Vdoing | Copyright © 2020-2023
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式