javascript原型之保姆级讲解

news2024/9/29 23:31:14

目录

  • 前言
  • 一,面向对象编程
    • 1.1 面向过程与面向对象
    • 1.2 JS创建类和对象
    • 1.3 类的继承
    • 1.4 Super关键词
    • 1.5 几个注意点
  • 二,构造函数原型
    • 2.1 创建对象的三种方法
    • 2.2 静态成员和实例成员
    • 2.3 构造函数的弊端
    • 2.4 函数的共享-原型prototype
    • 2.5 对象原型___proto__
    • 2.6 constructor构造函数
    • 2.7 构造函数、实例、原型对象三者之间的关系
    • 2.8 原型链
    • 2.9 对象成员查找规则
    • 2.10 this的指向问题
    • 2.11 原型对象的运用
  • 后记

前言

在学习了javascript基础后,我们应当去深层次的学习ES6。ES6有许多新特性,都将广泛运用于项目中。并且在企业的面试中,对ES6的考察也非常细致。

而es6中,笔者认为最难的部分是js的原型。本节就从面向对象开始,为大家逐渐深入原型讲解。原型方面的知识会涉及到后面对框架的理解,希望大家重视,也希望本节内容能帮助到大家!

一,面向对象编程

1.1 面向过程与面向对象

学过java,c++的同学应该能够理解面向对象。这里用通俗的语言对面向过程与面向对象做一个简单的介绍:

什么是面向过程?

面向过程的编程是以过程为中心进行编程。面向过程更注重因果关系,比如我要解决一个问题,我应该怎么做,我给出具体解法,让程序跑起来,最后解决问题。典型的是C语言。

什么是面向对象?

面向对象的编程是以对象为中心进行编程。它把很多个问题分成类,在写出一类问题的解法。比如我今天有一个问题需要解决,于是这个问题就是‘对象’,我去查找这一类问题怎么解决,这一类问题就是‘类’。面向对象就是把每个问题看成对象,调用这个对象对应的类下的方法来解决问题。典型是java语言,c++语言。

想要知道更多,读者可以去搜集更多面向对象的文档学习。

1.2 JS创建类和对象

创建类:

class 类名{
	方法1() {}
	方法2() {}
}

实例对象:

var 对象名 = new 类名()

于是,该对象可以调用该类中的方法,访问类中的数据。

具体参见下面实例:

        class Star {
            constructor(uname) {
                this.uname = uname;
            }
            sing() {
                console.log('我唱歌');
            }
        }
        //创建对象new
        var ldh = new Star('ldh');
        console.log(ldh.uname);
        ldh.sing();

这里需要注意,一般类名需要大写。

1.3 类的继承

这里举一个简单的例子。你的爷爷是一个百万富翁,你的爸爸继承了你爷爷的钱,并且他用这笔钱拿去赚钱翻倍成了千万富翁。你爸爸继承了你爷爷的东西,这是继承;他用这些东西,做了别的事情,这是继承的重要意义。

现在我们来学习具体定义:
父类/子类:已有类为父类,新建类为子类。
继承:一个类从另一个已有的类获得其特性,称为继承。
简单理解:某个类A具有某些特征,另一个类B,也具有A类的所有特征,并且还可能具有自己的更多的一些特征,此时,我们就可以实现:B类使用A的特征信息并继续添加自己的一些特有特征信息。

现规定,父类为A,子类为B,子类继承父类的格式:

class B extends A;

子类继承父类,可以使用父类中的方法,例子如下:

        class Father {
            constructor(x, y) {
                this.x = x;
                this.y = y;
            }
            sum() {
                console.log(this.x + this.y); 
            }
        }
        class Son extends Father {
            constructor(x, y) {
                super(1, 2);//调用了父类中的构造函数
            }
        }
        var son = new Son(1,2);
        son.sum();

在这里插入图片描述

1.4 Super关键词

子类在继承父类时可以调用父类的方法,也可以给自己新增方法。倘若父类中有一个方法名字为say,子类也有一个方法名为say,会如何呢?
请看如下代码:
在这里插入图片描述
最后的结果是子类中的方法覆盖了父类中的同名方法
在这里插入图片描述
此时有一个需求,我们需要调用父类中的say,该如何调用?这里就需要关键词Super了。使用supper可调用父类中的原型方法:

super.方法名

在这里插入图片描述
结果:
在这里插入图片描述

1.5 几个注意点

点一:在ES6中没有变量提升,所以要先定义类再实例化对象;
点二:类里面的共有属性与方法一定加this使用;
点三:实例对象中的this指向的是this对象,方法中的this指向的是方法的调用者。

二,构造函数原型

在ES6类与对象之前,通过构造函数和原型实现类的机制。

2.1 创建对象的三种方法

法一:利用new object()创建:

var obj = new object()

法二:利用对象字面量创建:

var obj1 = {}

法三:构造函数创建对象:
构造函数创建类,类创建对象:

function Start(uname, age) {
	this.uname = uname;
	this.age = age;
	this.call = function() {
		console.log(this)
	}
}
var ldh = new Start('Ann', 12);
Obj.sex = '男'//静态成员

构造函数创建对象一共四步,首先,系统会在内存中创建一个空对象;让this指向这个对象;然后执行构造函数内部代码给新对象提供属性和方法;最后返回这个新对象。

2.2 静态成员和实例成员

实例成员是构造函数内部通过this添加的成员,上述代码中uname,age,call就是实例成员;

静态成员在构造函数本身上添加的成员,sex就是静态成员,静态成员只能通过构造函数访问,不能通过对象访问。

2.3 构造函数的弊端

构造函数方法好用,但是存在消费内存的行为:我们用构造函数的方法创建了一个类,但是在创建对象的时候,实际上是开辟了多个空间去存放多个对象的,如下图,比较的是两者的地址,地址是不一样的。在这里插入图片描述在这里插入图片描述

2.4 函数的共享-原型prototype

构造函数通过原型分配的函数时所有对象所共享的。

JavaScript规定,每一个构造函数都有一个prototype属性,指向另一个对象。这个prototype本身就是一个对象,这个对象的所有属性和方法,都会被构造函数所拥有。

那么我们现在来打印一下Star构造函数,看看它有没有prototype:
在这里插入图片描述
注意,console.dir能够显示一个对象所有的属性和方法。
在这里插入图片描述
我们可以把那些不变的方法,直接定义在prototype对象上,这样所有的对象实例就可以共享这些方法。

所以,我们通常不把这些方法放在构造函数里面,而是放在原型对象上。
在这里插入图片描述
在这里插入图片描述
依旧可以正常输出,我们成功的实现了对象的共享。

2.5 对象原型___proto__

对象为什么能访问原型上的方法?

因为对象都有一个__proto__属性指向构造函数的prototype原型对象

如何证明:
在这里插入图片描述
在这里插入图片描述
这里需要了解方法的查找规则:先看看对象上有没有本身的方法,如果有就执行,如果没有,因为有__propo__的存在,就去构造函数原型对象prototype身上查找该方法。
在这里插入图片描述
proto只读不写。(这里就好像vue中的prop,只读不写)

2.6 constructor构造函数

对象原型(proto构造函数(prototype)原型对象里面都有一个属性,constructor属性,我们称为构造函数,因为它指回构造函数本身。
目的:记录用哪个构造函数创建出来的。
在这里插入图片描述
在这里插入图片描述
现在我们来查看下constructor是什么:
在这里插入图片描述
在这里插入图片描述
都指向了它们的构造函数。
这里注意,方法的添加不能用这种格式:
在这里插入图片描述
因为这样做会覆盖掉prototype,所以我们如果要修改原型对象,只能手动去添加。

2.7 构造函数、实例、原型对象三者之间的关系

在这里插入图片描述

2.8 原型链

从上面的讲述可知,只要是对象都有__proto__原型的存在,指向原型对象。原型对象也是对象,我们可以看看原型对象中有没有__proto__的存在:
原型对象:
在这里插入图片描述
在这里插入图片描述
里面依旧存在__proto__。并且,它等于Object.prototype:
在这里插入图片描述
在这里插入图片描述
那么,Object的原型对象的原型对象又是谁呢:
在这里插入图片描述
答案为空,已经到了最顶层。
在这里插入图片描述
所以,我们可以划出完整的原型链:
在这里插入图片描述

2.9 对象成员查找规则

当访问一个对象的属性(包括方法),首先查找这个对象自身有没有该属性;
如果没有就查找它的原型(__proto__指向的==prototype原型对象);
如果还没有就查找原型对象的原型(Object原型对象);
以此类推一直找到Object为止(null);
__proto__对象原型的意义就在于为对象成员查找机制提供一个方向,或者说一条路线。

2.10 this的指向问题

在构造函数中this指的是对象实例;
原型对象函数里面的thi指向的是实例对象:
在这里插入图片描述
在这里插入图片描述

2.11 原型对象的运用

扩展内置对象,可以通过原型对象,对原来的内置对象进行扩展自定义的方法。比如给主族增加自定义求和属性:

        Array.prototype.sum = function() {
            for(var i = 0; i < this.length; i++) {
                sum = sum + this[i];
            }
            return sum;
        }

数组和字符串内置对象不能给原型对象覆盖操作Array.prototype = {},只能是Array.prototype.xxx = function(){}的方式。

后记

本节主要讲述js原型的相关知识,逻辑可能稍微有些混乱,如果有问题希望大家能帮我指出,欢迎关注!

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

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

相关文章

用Python制作你的专属音乐播放器(此刻浪漫只属于你哦*´▽`*)

文章目录前言一、项目介绍二、环境配置三、代码实战前言 昨天是博主的一位朋友生日&#xff0c;除了送上大大的红包&#xff0c;知道他喜欢听音乐&#xff0c;特意用代码给他写了一个 专属音乐播放器&#xff0c;今天把这个代码也开源送给所有粉丝哦。 一、项目介绍 我们常用…

Vue--》实现动画与过渡效果

目录 动画效果 过渡效果 第三方动画库 Vue封装的过渡与动画作用是在插入、更新或移除DOM元素时&#xff0c;在合适的时候给元素添加类名。 动画效果 操作css的trasition或animation&#xff0c;vue会给目标元素添加/移除特定的class&#xff0c;过渡的相关类名是&#xff1…

Spring项目中用了这种解耦模式,经理对我刮目相看

前言 不知道大家在项目中有没有遇到过这样的场景&#xff0c;根据传入的类型&#xff0c;调用接口不同的实现类或者说服务&#xff0c;比如根据文件的类型使用 CSV解析器或者JSON解析器&#xff0c;在调用的客户端一般都是用if else去做判断&#xff0c;比如类型等于JSON&…

【Spring6源码・IOC】Bean的实例化

上一节我们讲到《【Spring6源码・IOC】BeanDefinition的加载》&#xff0c;这一节我们来讲解一下Bean的实例化。 根据xml或注解加载完Bean的信息后&#xff0c;最终会通过反射来创建bean的对象。 invokeBeanFactoryPostProcessors()主要是加载BeanDefinition。 finishBeanFa…

MAC(m1)-VMWare Fusion安装CentOS7.9(续)

下载了CentOS8&#xff0c;优先安装CentOS8 默认的配置有点小, 可以根据自己需求进行自定义设置&#xff1a; 点击存储&#xff0c;会出现&#xff1a; 咱们是中国人&#xff0c;优先选择中文&#xff1a; 点击网络和主机名&#xff0c;配置网络&#xff1a; 打开网卡开关&…

找出给定数组中和是给定目标整数的两个整数,输出找到的两个整数下标

找出给定数组中和是给定目标整数的两个整数&#xff0c;输出找到的两个整数下标。 (本文获得CSDN质量评分【x】)【学习的细节是欢悦的历程】Python 官网&#xff1a;https://www.python.org/ Free&#xff1a;大咖免费“圣经”教程《 python 完全自学教程》&#xff0c;不仅仅…

Android---简易Snackbar

目录 Snackbar 简介 Snackbar 特性 完整Demo Snackbar 简介 Snackbar 是 Android5.0 新特性---Material Design 中的一个控件&#xff0c;用来代替 Toast。Snackbar 就是一个类似 Toast 的快速弹出消息提示的控件&#xff0c;手机上显示在底部&#xff0c;大屏幕设备显示在左…

Golang实现分布式锁

1. go实现分布式锁 通过 golang 实现一个简单的分布式锁&#xff0c;包括锁续约、重试机制、singleflght机制的使用 1.1 redis_lock.go package redis_lockimport ("context"_ "embed""errors""github.com/go-redis/redis/v9""…

Java Netty框架自建DNS代理服务器教程

前言 DNS协议作为着互联网客户端-服务器通信模式得第一关&#xff0c;在当下每天都有成千上亿上网记录产生得当今社会&#xff0c;其重要性自然不可言喻。在国内比较有名得DNS服务器有电信得114.114.114.114、阿里云得223.5.5.5&#xff0c;DNSPod得119.29.29.29&#xff0c;配…

【矩阵论】8. 常用矩阵总结——镜面阵,正定阵

8.4 镜面阵 法向量确定一个镜面 8.4.1 镜面阵的作用 对法向量 Aα−αA\alpha-\alphaAα−αA(Aα)A2ααA(A\alpha)A^2\alpha\alphaA(Aα)A2αα 对镜面上向量 AYYAYYAYY 8.4.2 镜面阵表示 AIn−2ααH∣α∣2,其中α(x1x2⋮xn)∈Cn,且α≠0AI_n-\frac{2\alpha\alpha^H}{\…

【实际开发02】- 同模块 - 单表 CRUD 代码 - 批量操作

目录 0. yml 配置 1. 账号 / 密码 等有概率变更的信息 推荐 动态配置 , 避免写死 1. entity 处理 ( 减少后续 insert/update 判空处理 ) 1. volidation.annotation 配合 Valid - 参数校验 2. Validated - ( 相较于 valid 更加严谨的校验 ) 1. Save / Status 2. Update /…

vue中使用axios

一、axios axios是一个基于Promise的网络请求库。既可以在node.js&#xff08;服务器端&#xff09;使用&#xff0c;也可以在浏览器端使用 1. 在node.js中使用的原生的http模块 2. 在浏览器中使用的XMLHttpRequest 二、vue中的使用方法 1. 安装&#xff1a;npm install axios…

二分查找及其扩展

目录 二分查找算法思想&#xff1a; 循环 递归 有多个与key相等数据的查询&#xff0c;找最左边与关键字相等的那个 找第一个大于key的元素的下标 有序循环数组的二分查找 二分查找算法思想&#xff1a; 二分查找也叫折半查找&#xff0c;查找效率较高。但是查找的线性表…

振弦采集模块电子标签测量(智能振弦传感器)

振弦采集模块电子标签测量&#xff08;智能振弦传感器&#xff09; 此功能在 SF3.52 版本时增加。 固件版本 V3.52 修改固件版本号为 V3.52_2201009。 增加了电子标签测量功能。 WKMOD.[12]用于控制是否使用此功能 新增状态位 STATUS.[13]&#xff0c;用来表示是否检测到了电子…

JAVA开发运维(DevOps过程)

DevOps开发运维的一套方法论。这边文章主要借鉴万达的DevOps的建设过程。谈谈DevOps主要解决那些问题和怎么解决。DevOps的是一种IT项目开发管理方法论&#xff0c;它旨在提供全面的持续集成、持续交付等能力&#xff0c;并持在续进行过程度量和改进&#xff0c;不断提升 IT 运…

新电脑安装vmware和centos8系统

1.安装vmware 1.1.vmware官网下载 需要付费 1.2.使用指定破解版本 链接&#xff1a;https://pan.baidu.com/s/1YEeaDyKAQk_3t6ITw2aaTQ 提取码&#xff1a;fjyf vmware16最新许可证密钥&#xff1a; ZF3R0-FHED2-M80TY-8QYGC-NPKYF YF390-0HF8P-M81RQ-2DXQE-M2UT6 ZF71R-DMX…

HTML实现网站欢迎页过渡

演示 一秒后直达主界面 css html, body {background: radial-gradient(#181818, #000000);margin: 0;padding: 0;border: 0;-ms-overflow-style: none;}::-webkit-scrollbar {width: 0.5em;height: 0.5em;background-color: #c7c7c7;}/*定义滚动条轨道 内阴影圆角*/::-webkit…

c++11 标准模板(STL)(std::forward_list)(二)

定义于头文件 <forward_list> template< class T, class Allocator std::allocator<T> > class forward_list;(1)(C11 起)namespace pmr { template <class T> using forward_list std::forward_list<T, std::pmr::polymorphic_…

什么是数字孪生城市

数字孪生城市理念自提出以来不断升温&#xff0c;已成为新型智慧城市建设的热点&#xff0c;受到政府和产业 界的高度关注和认同。 什么是数字孪生城市 北京智汇云舟科技有限公司成立于2012年&#xff0c;专注于创新性的“视频孪生&#xff08;实时实景数字孪生&#xff09;”…

【Java编程进阶】Java抽象类与接口详解

推荐学习专栏&#xff1a;Java 编程进阶之路【从入门到精通】&#xff0c;从入门到就业精通&#xff0c;买不了吃亏&#xff0c;买不了上当&#xff01;&#xff01; 文章目录1. 抽象类2.接口3. 抽象类和接口对比4. 总结Java基础教程系列文章1. 抽象类 前面说到&#xff0c;Ja…