面向对象编程/原型及原型链

news2024/11/20 7:21:21

一.面向对象

(1)对象是什么?为什么要面向对象?

通过对代码的抽象,进而描述单个种类物体的方式.

(2)特点:面向对象-逻辑上迁移更加灵活,代码的复用性更高,高度的模块化.

(3)对象的理解

1.对象是对于单个物体的简单抽象;

2.对象是容器,封装了属性和方法

**属性:对象状态

**方法:对象的能力/行为

        //简单对象
        const Course = {
            teacher: 'tom',
            leader: 'xh',
            startCourse: name => {
                return `开始${name}课`
            }
        }
        //A同学
        Course.teacher = 'xxx'
        Course.startCourse('react')

        //B同学
        Course.startCourse('vue')  //发现即使课变了,但是老师也被修改了

        //引出函数对象
        function Course(){
            this.teacher='tom'
            this.leader='xh'
           this.startCourse= name => {
                return `开始${name}课`
            }
        } 

##构造函数

####需要一个模板-表征了一类物体的共同属性,从而生成对象.

####类即对象模板

#### js本质并不是基于类,而是基于构造函数+原型链

### Course本质就是构造函数

*1.函数体内使用的this,指向所要生成的实例;

2.生成对象用new来实例化;

3.可以初始化传参.

       function Course() {
            this.teacher = 'tom' //这里的this其实指向course 这个实例对象
            this.leader = 'xh'
            this.startCourse = name => {
                return `开始${name}课`
            }
        }
        const course = new Course(args)

####追问:如果构造函数不初始化,可以使用具有相同能力吗?->无法具有

####如果在项目中需要使用,且不希望外界进行感知情况下,如何让外界直接拿到实例化后的对象?=>单例模式

       function Course() {
            const _isClass = this instanceof Course
            //未实例化
            if (!_isClass) {
                return new Course
            }
            this.teacher = 'tom'
            this.leader = 'xh'
            this.startCourse = name => {
                return `开始${name}课`
            }
        }
        //使用方
        const course=Course()

启发:编写底层api代码时,尽量做到不让外界去感知区分内部类型.

####引发思考:new是什么?/new的原理是什么?/new的时候做了什么?

        function Course() { }
        const course = new Course()

*总结:1.结构上:创建了一个空对象,作为返回的对象实例;

2.属性上:将生成空对象的原型对象指向了构造函数的prototype属性;

3.关系上:将当前实例对象赋值给了内部的this;

4.生命周期上:执行了构造函数的初始化代码.

####追问:实例属性影响-独立的

function Course(teacher, leader) {
            this.teacher = teacher
            this.leader = leader
        }
        const course1 = new Course('tom', 'xh')//course1.teacher ->tom
        const course2= new Course('steven', 'bubu')//course2.teacher ->steven
        course2.teacher='xxx'//course.teacher=>tom
        //分析过程:course1 是构造函数的实例化对象,而this指向了这个实例化对象,所以this.teacher和this.leader 
        //是实例化对象上的属性,而构造函数new Course时,调用了Course()这个函数传入的参数,所以实例化对象的teacher
        //属性也就指向了调用Course()这个函数传入的参数.

###拔高:用js手写一个new

        function usernew(obj, ...args) {
            const newObj = Object.create(obj.prototype)
            const result = obj.apply(newObj, args)
            return typeof result === 'object' ? result : newObj
        }

 ###constructor是什么?

        function Course(teacher, leader) {
            this.teacher = teacher
            this.leader = leader
        }
        const course1 = new Course('tom', 'xh')//course1.teacher ->tom

*1.每个对象创建时,会自动拥有一个构造函数属性constructor;

2.constructor源自原型对象,指向了构造函数的引用.

*实例获得了模板的属性=>(大胆点)继承了类的属性

####原型对象

        function Course(){}
        const course1 = new Course()
        const course2 = new Course()
        //1.Course - 用来初始化创建对象的函数 | 类
        course1.__proto__===Course.prototype
        //2.course1 - 根据原型创建出来的实例
        course1.constructor===Course

*prototype是什么?

        function Course() {
            this.teacher = 'tom'
            this.leader = 'xh'
        }
        Course.prototype.startCourse = name => {
            return `开始${name}课`
        }
        const course1 = new Course()

*追问:原型对象有自己的原型链吗?

        course1.__proto__.__proto__ === Object.prototype
        Course.prototype.__proto__ === Object.prototype
        course1.__proto__.__proto__.__proto__ === null

原型链

 

完整的原型图:

**继承

js如何实现继承?

####在原型对象的所有属性方法,都可以被实例所共享

        function Game() {
            this.name = 'lol'
        }
        Game.prototype.getName = function () {
            return this.name
        }
        //LOL
        function LOL() { }
        LOL.prototype = new Game()//将LOL的原型对象指向Game的实例
        LOL.prototype.constructor = LOL
        const game = new LOL()

本质:重写了原型对象方式,将父对象的属性方法,作为自原型对象的属性方法,同时重写构造函数.

####追问:原型链直接继承,有什么缺点?

        function Game() {
            this.name = 'lol'
            this.skin=['s']
        }
        Game.prototype.getName = function () {
            return this.name
        }
        function LOL() { }
        LOL.prototype = new Game()//将LOL的原型对象指向Game的实例
        LOL.prototype.constructor = LOL
        const game1 = new LOL()
        const game2 = new LOL()//game2也会拿到新添加的属性值
        game1.skin.push('ss')

*1.父类属性一旦赋值给子类的原型属性,此时属性属于子类得共享属性了;

*2.实例化子类时,元素无法向父类进行传参.

###解决方法:构造函数继承

####经典继承:在子类得构造函数内部使用父类的构造函数

        function Game(args) {
            this.name = 'lol'
            this.skin = ['s']
        }
        Game.prototype.getName = function () {
            return this.name
        }
        function LOL(args) {
            Game.apply(this, args)//调用Game的this,并传递参数
        }
        const game3 = new LOL('args')

解决了共享属性问题+子向父传参的问题.

###追问::原型链上的共享方法无法被读取继承,如何解决?

####组合继承

        function Game(args) {
            this.name = 'lol'
            this.skin = ['s']
        }
        Game.prototype.getName = function () {
            return this.name
        }
        function LOL(args) {
            Game.apply(this, args)//调用Game的this,并传递参数
        }
        LOL.prototype = new Game()//调用
        LOL.prototype.constructor = LOL
        const game4 = new LOL('args')//调用

###追问:组合继承缺点?问题在于,无论何种场景,都会调用两次父类的构造函数.

###解决方案:寄生组合继承

        function Game(args) {
            this.name = 'lol'
            this.skin = ['s']
        }
        Game.prototype.getName = function () {
            return this.name
        }
        function LOL(args) {
            Game.apply(this, args)//调用Game的this,并传递参数
        }
        LOL.prototype =Object.create(Game.prototype)//关键点
        LOL.prototype.constructor = LOL
        const game5 = new LOL('args')//调用

###拔高:如何实现多重继承?

        function Game(args) {
            this.name = 'lol'
            this.skin = ['s']
        }
        Game.prototype.getName = function () {
            return this.name
        }
        function Store() {
            this.shop = 'steam'
        }
        Game.prototype.getPlatform = function () {
            return this.shop
        }
        function LOL(args) {
            Game.apply(this, args)//调用Game的this,并传递参数
            Store.apply(this, args)
        }
        LOL.prototype = Object.create(Game.prototype)//关键点
        // Store.prototype =Object.create(Game.prototype)会冲掉   LOL.prototype
        Object.assign(Store.prototype, LOL.prototype)
        LOL.prototype.constructor = LOL

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/755790.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Python官方文档中Availability: not Emscripten, not WASI是什么意思?

在我们阅读Python官方文档中,当某个模块或特性的文档中写着 "Availability: not Emscripten, not WASI" 时,它表示该模块或特性在 Emscripten 和 WASI 环境中不可用。 Emscripten 是一个工具链,用于将C和C代码编译为WebAssembly&am…

【Python从入门到进阶】28、xpath的安装以及使用

接上篇《27、Handler处理器使用及代理和Cookie登录实现》 上一篇我们讲解了urllib中Handler处理器的基本使用,以及实现代理访问和Cookie的登录。本篇我们来讲解HTML文档解析中的核心插件xpath的安装及使用。 一、xpath介绍 XPath是由W3C(World Wide We…

kotlin中使用Room数据库(包含升降级崩溃处理)

目录 1.导入依赖库 2.数据实体类 3.数据访问对象 (DAO) 4.数据库类 5.调用DAO里面的“增、删、改、查”方法 6.数据库升降级处理 升级(保存数据库历史数据): 升级(不保存数据库历史数据): 降级&…

剑指 offer 数学算法题:数值的整数次方

题目描述: 实现 pow(x, n) ,即计算 x 的 n 次幂函数(即,xn)。不得使用库函数,同时不需要考虑大数问题。 分析: 直接计算法,通过判断 n 的正负,若为负数, x 即…

无法加载文件\venv\Scripts\Activate.ps1,因为在此系统上禁止运行脚本

一、问题发生 运行环境Windows 10、python 3.11.1、IDE VScode 当然你可能使用了其他IDE,例如pycharm等,不过没有关系解决问题的方法都是一致的。 报错信息如下图所示: actvivate.ps1这个脚本文件是用来激活python虚拟环境的。 其实&…

LabVIEW开发图像采集和图像处理程序

LabVIEW开发图像采集和图像处理程序 扫描电子显微镜(SEM)是一种功能强大的工具,广泛用于高分辨率的生物和半导体样品检测。然而,对于大面积或3D成像,SEM成像是一个耗时的过程。MBSEM旨在通过同时扫描多个像素来减少采…

spring5源码篇(10)——spring-aop代理过程

spring-framework 版本:v5.3.19 文章目录 1、ProxyFactory1.1、createAopProxy() 创建AopProxy1.2、getProxy() 创建代理对象1.3、JdkDynamicAopProxy#invoke 代理逻辑1.3.1、advised.getInterceptorsAndDynamicInterceptionAdvice() 匹配添加的advisor并转化成所需…

集群基础3——haproxy负载均衡apache

文章目录 一、环境说明二、安装配置httpd三、安装配置haproxy四、验证http负载均衡五、配置https负载均衡六、haproxy网页监控6.1 监控参数详解6.2 页面操作 一、环境说明 使用haproxy对apache进行负载均衡。 主机IP角色安装服务真实IP:192.168.161.129VIP&#xff…

通识强化学习,初步了解强化学习的运行规则和估值方法

1.强化学习的发展及应用现状 1.1.强化学习的由来 目前,大家认为强化学习(Reinforcement Learning, RL)的来源与两个领域密切相关:即心理学的动物试错学习和最优控制的优化理论。 这里都是有相应的共性的,在environme…

PostgreSQL MVCC的弊端优化方案

我们之前的博客文章“我们最讨厌的 PostgreSQL 部分”讨论了大家最喜欢的 DBMS 多版本并发控制 (MVCC) 实现所带来的问题。其中包括版本复制、表膨胀、索引维护和真空管理。本文将探讨针对每个问题优化 PostgreSQL 的方法。 尽管 PostgreSQL 的 MVCC 实现是 Oracle 和 MySQL 等…

java每日一题:HashMap的工作原理

面试官:欢迎参加我们的面试。请你解释一下Java中HashMap的工作原理。😊 面试者:HashMap是一种基于哈希表的数据结构,它可以存储键值对。在HashMap内部,使用一个数组来存储数据,数组中的每个位置被称为桶&a…

生信分析案例 Python简明教程 | 视频11

开源生信 Python教程 生信专用简明 Python 文字和视频教程 源码在:https://github.com/Tong-Chen/Bioinfo_course_python 目录 背景介绍 编程开篇为什么学习Python如何安装Python如何运行Python命令和脚本使用什么编辑器写Python脚本Python程序事例Python基本语法 数…

C语言之每日一题——杨氏矩阵

今天分享的是杨氏矩阵,题目不是特别难,但是是一道比较考验你对杨氏矩阵的理解,要是你不知道杨氏矩阵的话,那你这道题目就无从下手 杨氏矩阵我们可以这样理解,首先矩阵二字证明他是一个长方形型或者正方形的数组&#x…

【HarmonyOS】元服务隐私协议开发指导样例

【关键字】 隐私、弹窗、元服务、协议 【介绍】 每个元服务必须提供隐私声明,否则将导致提交元服务发布上架时,审核无法通过。隐私声明的具体要求请参见隐私声明规范。用户使用元服务前,必须引导其了解隐私声明信息,获取用户授权…

3.SpringBoot 返回Html界面

1.添加依赖spring-boot-starter-web <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency>2.创建Html界面 在Resources/static 文件夹下面建立对应的html&#xff0c…

【亮点回顾】第四届国有企业数智化采购与智慧供应链论坛

7月12日&#xff0c;由中国物流与采购联合会主办、北京筑龙承办的“第四届国有企业数智化采购与智慧供应链论坛”在北京市盛大举行。本届论坛以“数智赋能创新发展”为主题&#xff0c;立足于国有企业采购领域发展前沿&#xff0c;深度聚焦国有企业如何在数字经济发展中发挥引领…

【uView 1.x】中国省市县/区 地区选择器picker【亲测可用】

如果你还没安装uView&#xff0c;请先安装uView 注意&#xff1a;这是uView1.x Picker选择器的用法&#xff0c;uView2.x Picker选择器中没有mode属性 效果图&#xff1a; 把u-picker的mode设置为region地区模式&#xff0c;然后展示在u-input中。 由于uview中自带城市数据包…

echart折线图背景颜色自定义,实心圆点,虚线网格等功能

需求&#xff1a;根据传入的值对背景进行分层颜色展示&#xff0c;比如y轴20-40区间颜色为蓝色&#xff0c;40-50为红色这种&#xff0c;折线图的小圆点设置为实现&#xff0c;实现缩放功能 1.效果如下 2.代码讲解如下 首先下载echarts npm install echarts4.9.0 -S 我这边…

LeetCode·每日一题·931. 下降路径最小和·记忆化搜索

作者&#xff1a;小迅 链接&#xff1a;https://leetcode.cn/problems/minimum-falling-path-sum/solutions/2341965/ji-yi-hua-sou-suo-zhu-shi-chao-ji-xiang-3n58v/ 来源&#xff1a;力扣&#xff08;LeetCode&#xff09; 著作权归作者所有。商业转载请联系作者获得授权&am…

Mysql单表多表查询练习

题目要求&#xff1a; 1.查询student表的所有记录 2.查询student表的第2到4条记录 3.从student表查询所有的学生的学号&#xff08;id&#xff09;&#xff0c;姓名&#xff08;name&#xff09;&#xff0c;和院系&#xff08;department&#xff09;的信息 4.从student表…