JavaScript 高级3(构造函数,原型-对象、继承)
创始人
2024-04-29 20:34:00
0

JavaScript 高级

1、编程思路

1.1、了解-面向过程与面向对象

  • 面向过程

    分析问题中的关键步骤,并将步骤封装成函数,然后按顺序依次调用即可。

  • 面向对象

    分析问题中的关系步骤,将这些步骤划分到不同的主体(对象)上,然后按顺序依次调用主体上的方法即可。

    封装对象其实并不是为了解决问题,而是为了表示函数的所属关系。

  • 代码演示

    
    
    Document
    
    
    
    

1.2、了解-面向对象的三大特性

  • 封装

    严格的来按面向对象的思想来书写代码。

  • 多态

    多种形态。

  • 继承

    一个对象使用另一个对象上的属性或方法

👉 以上三大特性是纯正的面向对象语言所具有的,但JavaScript并不是基于对象的语言,并不是面向对象的语言,所以,这三大特性在JS中的体现并不明显。

2、构造函数

2.1、体现封装

👉 构造函数,是面向对象三大特性的封装性的体现。

  • 其目的

    将数据与操作数据的方法定义到一个主体上,方法内通过this来访问数据。

    实例化出来的每个对象上各自保留有自己的数据与操作数据的方法。

  • 示例代码

    /* 
    构造函数就是面向对象三大特性之一,封装性,在JS这种语言中的代码体现。
    */
    function Person(){this.age = 20;          // 数据保存到对象的属性上this.say = function(){// 将操作数据的代码写到对象的方法上。   console.log(this.age);}
    }let obj = new Person()
    obj.age
    obj.say()// 通过构造函数,将数据,以及操作数据的代码,封装一对象上// 封装性代码体现就是,构造函数,
    

2.2、内存浪费

  • 思考

    同一个构造函数实例化出来的对象,每个对象上会保存各自的属性与方法。

    对于属性中所保存的数据,很多时候是不同的,所以每个对象要有各自的属性。

    但对于方法,来自同一个构造函数实例化出来的对象,所有的方法都是相同的,每个对象都保存一份,这会造成内存的浪费。

  • 验证代码

    === 可以验证是不是同一个对象,同一个对象,同一个方法。

    // 本小节主要引出一个小问题,通过这个问题去引出另一个知识点。
    function Person(a,n){// 由于每个对象的属性数据不同,所以不写死,动态传递this.age = athis.name = n// 由于每个对象方法代码一般都是相同的,所以直接写死this.say = function(){// 无论当前构造函数,new出多少个对象,同一个方法内的代码是相同的,}
    }let oa = new Person(20,'zhangsan')
    let ob = new Person(22,'lisi')console.log(oa);
    console.log(ob);console.log(oa.say === ob.say);            // false

3、原型对象

3.1、简介

  • 原型对象

    在JS中只要有一个函数存在,JS就会创建一个与之对应的对象。这个对象就是原型对象。

    这个对象只有一个属性 constructor

  • 原型对象的访问

    原型对象不可以直接访问,只能通过函数或实例对象间接访问。

    • 函数.prototype
    • 实例对象.proto
  • 示例代码

    function Fn(){}
    console.log(Fn.prototype);let obj = new Fn();
    console.log(obj.__proto__);
    

3.2、构造函数与原型对象之间的关系

👉 构造函数与原型对象之间的关系 主要是体现在以下两个属性的相互指向上。

  • prototype

    构造函数.prototype 指向 原型对象

  • constructor

    原型对象.constructor 指向 构造函数

  • 示例代码

    function Person(){}// 构造函数是通过 prototype属性 "指向" 原型对象
    console.log(Person.prototype);// 构造函数是通过 contructor 属性 "指向" 构造函数
    console.log(Person.prototype.constructor);console.log(Person.prototype.constructor === Person);
    

3.3、实例对象与原型对象之间的关系

👉 实例对象与原型对象之间的关系 主要是体现在__proto__这个属性上。

  • _proto_

    实例对象._proto_ 指向 原型对象

  • 示例代码

    
    
    Document
    
    
    
    

3.4、构造函数、原型对象、实例对象的三角关系

👉 三角关系的主要体现在三个属性上

  • prototype

    构造函数.prototype 指向 原型对象

  • constructor

    原型对象.constructor 指向 构造函数

  • _proto_

    实例对象._proto_ 指向 原型对象

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kGgmVTIx-1671867193274)(./assets/image-20220623142235739.png)]

3.5、原型对象的特点

  • 原型对象上的成员会被所有的实例对象所共享

    就是当一个实例对象访问某个成员时,如果不存在会自动到原型对象上找。

  • 示例代码

    // 首先在JS中任何一个对象上一级都有它的原型对象// 原型对象的特点
    //  当某一个对象,访问一个成员(属性或方法)不存在时,会自动到它的原型对象上找这个成员进行使用。function Person(){// this.age = 20;}// 在原型对象上添加一个属性 age
    Person.prototype.age = 22let oa = new Person()console.log(oa.age);
    

👉 使用原则:所有实例共享(一份)保存到原型对象上,如果每个实例都要独有的(多份)定义在构造函数内。

4、原型继承

4.1、修改prototype指向

  • 原型对象也是可以被替换掉的

    修改之前实例化的对象,访问之前的原型对象上的方法

    修改之后实例化的对象,访问之后的原型对象上的方法

  • 示例代码

    // 默认:函数的原型对象是系统创建的,这个原型对象是可以被修改。
    function Person(){}Person.prototype.a = 20;let oa = new Person();
    console.log(oa.a);let abc = {}// ------------ 修改prototype的指向(让prototype属性指向另一个对象)
    Person.prototype = abc// 修改之后,实例化另一个对象
    let ob = new Person();console.log(ob.a);
    console.log(oa.a);
    

4.2、原型继承

👉 在JS中继承的方法有很多,这里我们只了解一种常用的 原型继承

  • 原型继承

    原型继承也称之为替换原型继承。

    主要思想是 使用父的实例对象来替换子的原型对象。

  • 代码实现:

    // 继承:
    //      一个对象使用另一个对象上的成员//      使用父的实例(实例对象),来替换子的原型function A(){           // 父this.x = 100;this.y = 200;}let oA = new A()        // 这是父的一个实例对象function B(){           // 子}          // 使用父的实例(实例对象),来替换子的原型
    B.prototype = oAlet oB = new B()
    console.log(oB.x);
    console.log(oB.y);/* 
    小结:JS中继承实现有很多种,使用父的实例,来修改子的原型。*/
    

5、原型链

5.1、什么是原型链

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-OUMPT6sI-1671867193278)(assets/image-20220717153152960.png)]

  • 什么是原型链

    原型链是由原型对象形成的一个链条。

    👉 原型链是通过__proto__形成的链接

  • 示例代码

    // 原型链:由原型对象形成的一个"链条"function Person(){}let oa = new Person()// 当一个对象访问某个成员,成员不存在时,会自动到原型对象上找。
    // console.log(oa.age);// 原型对象也是对象,原型对象上在查找age属性时,
    // 如果没有,会到原型对象的原型对象上找这个属性
    console.log(Person.prototype);    // 一级原型
    console.log(Person.prototype.__proto__);  // 二级原型
    console.log(Person.prototype.__proto__.__proto__);  // null// 默认每一个原型对象都有一个函数与之对应
    // 一级原型对应的构造函数 Person这个函数   二级原型对象的构造函数是 Object()
    // 验证 === 
    console.log(Person.prototype.__proto__.constructor === Object);
    

5.2、原型链的查找规则

  • 原型链的查找规则

    原型的作用是当实例对象上访问某个成员不存在时,则会到原型对象上找。

    而原型链是当原型对象上访问某个成员不存在时,会到原型对象的原型对象上找。

    这样就形成了一级一级向上找的过程。

    就近原则,

  • 示例代码

    function Person(){}// Person.prototype.n = 10;
    Person.prototype.__proto__.n = 20;let oa = new Person();
    console.log(oa.n);
    

5.3、instanceof 运算符

  • 语法:

    对象 instanceof 函数

  • 说明:

    作用于判断构造函数与实例对象的关系,

    依据是构造函数对应的原型对象是否在以实例为起点的原型链上。

  • 示例代码

    function Human(){}function Person(){}let oa = new Person();
    console.log(oa instanceof Person);      // true
    console.log(oa instanceof Human);       // false
    console.log(oa instanceof Object);       // true
    

6、面向对象-模态弹窗

6.1、封装构造函数

  • 面向对象思想分析

    采用面向对象思想,先找对象,我们将弹窗当成一个对象。

    构造函数体现面向对象代码体现,通过构造函数可以得到对象。

  • 对象设计

    弹窗标题 与 弹窗内容,可以看作是弹窗相关的数据,使用属性保存

    弹窗需要一个html标签来显示页面效果,这个标签也看作弹窗的属性

    弹窗要显示,所以弹窗需要具有显示的方法。

  • 实现

    function Modal(t, c) {this.title = tthis.content = cthis.el = document.createElement('div')this.el.className = 'modal'this.el.innerHTML = `
    ${this.title} x
    ${this.content}
    `this.show = function () {document.body.appendChild(this.el)} }// 测试:删除按钮事件 document.querySelector('#delete').addEventListener('click', function(){let oM = new Modal('温馨提示','您无权删除')oM.show() })// 测试:登陆按钮事件 document.querySelector('#login').addEventListener('click', function(){let oM = new Modal('登陆成功', '正在为您跳转')oM.show() })

6.2、实现模态弹窗

  • 分析

    同一时刻只能出现一个弹窗,这种就是模态弹窗

    弹窗显示时,先获取页面获取弹窗用到的标签,如果有则不显示第2个,如果没有才显示

  • 实现

    function Modal(t, c) {this.title = tthis.content = cthis.el = document.createElement('div')this.el.className = 'modal'this.el.innerHTML = `
    ${this.title} x
    ${this.content}
    `this.show = function () {// -------- 判断页面上是否有 弹窗存在if (!document.querySelector('.modal')) {document.body.appendChild(this.el)}} }// 测试:删除按钮事件 document.querySelector('#delete').addEventListener('click', function(){let oM = new Modal('温馨提示','您无权删除')oM.show() })// 测试:登陆按钮事件 document.querySelector('#login').addEventListener('click', function(){let oM = new Modal('登陆成功', '正在为您跳转')oM.show() })

6.3、实现关闭

  • 分析

    为关闭按钮注册事件,

    事件内从body标签中将弹窗删除

  • 实现

    function Modal(t, c) {this.title = tthis.content = cthis.el = document.createElement('div')this.el.className = 'modal'this.el.innerHTML = `
    ${this.title} x
    ${this.content}
    `this.show = function () {// 判断页面上是否有 弹窗存在if (!document.querySelector('.modal')) {document.body.appendChild(this.el)// -------- 为 关闭按钮 注册事件,document.querySelector('.modal .header i').addEventListener('click', function(){// -------- 在事件内将 .modal 元素从页面里移除即可document.body.removeChild(document.querySelector('.modal'))})}} }// 测试:删除按钮事件 document.querySelector('#delete').addEventListener('click', function(){let oM = new Modal('温馨提示','您无权删除')oM.show() })// 测试:登陆按钮事件 document.querySelector('#login').addEventListener('click', function(){let oM = new Modal('登陆成功', '正在为您跳转')oM.show() })

相关内容

热门资讯

16 | 如何做好面试后的复盘... 前言 前言:将经验转换为能力,就需要从经历的事情上总结复盘。 文章目...
Python基础学习七 类 Python从设计之初就已经是一门面向对象的语言,正因为如此,在Py...
day 19 暴力枚举 注意:用long long 存答案P2241 统计方形(数据加强版&#x...
嵌入式理论复习题库(期末考试版... 一、填空题15*1=15 1. 要下载并调试 STM32 程序,可采用   ...
OSG三维渲染引擎编程学习之二... 目录 第三章:OSG场景组织 3.6 Transform变换节点 第三章:OSG场景组织 ...
cmake 04 使用 pyt... 本文目标 使用 python 写一个管理 cmake 工程的 cli 程序 参考 Python CL...
Java多线程(二)—— Re... ReentrantLock源码解析 ReentrantLock 是可重入的互斥锁,虽然...
linux shell脚本学习 linux shell脚本学习笔记 文章目录linux shell脚本学习笔记一、脚本入门1.我的第...
【MySQL】第九部分 MyS... 【MySQL】第九部分 MySQL信息函数 文章目录【MySQL】第九部分 MySQL信息函数9....
StarRocks 集群安装部... 下表为规划的集群组件分配 域名starrocks1starrocks2starrocks3组件my...