前端知识体系:JavaScript基础-原型和原型链-理解原型设计模式以及 JavaScript中的原型规则
理解原型设计模式以及 JavaScript中的原型规则(原文地址)
1、原型对象:我们创建的每一个函数(JavaScript中函数也是一个对象)都有一个原型属性 prototype,原型属性实质上是一个指针,它指向一个对象,这个对象的用途是包含可以由特定类型的所有实例共享的属性和方法(通俗的说:就是这个特定类型的所有实例都可以共享原型对象包含的属性和方法)。
2、原型对象的两赋值方式:
①:

此时实例对象 person1 和 person2 的属性和方法都是用原型对象共享的,所以上面结果是:

②:

和创建一个引用对象一样,也可以采用字面量的形式给原型对象赋值。最终结果和上面结果相同,但是一个例外就是 constructor 属性不再指向Person了,因为字面量的方式重写了原型对象,此时 constructor 属性指向Object对象

但是我们可以指明 constructor 指向Person:

3、原型对象的内存分析:
引用《javascript高级程序第三版》中的内存分析图
Person构造函数、Person原型对象、Person现有的两个实例之间的关系:

每个函数都会有一个原型属性(prototype),它是一个指针,指向原型对象;默认情况下,原型对象包含一个constructor(构造函数)属性(原型最初只包含constructor属性),这个属性包含一个指向prototype属性的指针;如上图:Person.prototype.constructor指向Person,通过这个构造函数就可以继续为原型对象添加其他的属性和方法。
当调用构造函数创建一个新实例后,该实例内部会包含一个内部属性(指针),它指向构造函数的原型对象;这个连接存在于实例与构造函数的原型对象之间,而不是存在于实例和构造函数之间;也就是说这个内部属性和构造函数没有直接的关系。
4、原型对象中的值不能被对象实例重写:

测试结果:

可以看到原型对象中的name属性没有被改变,person1.name来自实例,person2.name来自原型。
在原型模式中当通过person1.name读取属性值时,首先会去实例上查找有没有名称为name的属性,有的话就不会再去原型对象上查找;如果实例上没有,就会去原型对象上搜索。
也就是说当我们给实例上添加了一个属性,这个属性就会阻止我们去原型上访问这个同名属性,但是不会修改那个属性。
内存分析,图中省略了与Person构造函数之间的关系:

通过delete操作符可以直接删除实例中的属性:delete person1.name
5、原型的动态性:
第4点说了不能通过对象实例来修改原型对象中的值,不是说原型对象中的值不能被修改,通过下面方式仍可进行修改:

测试结果:

由于在原型中查找的过程是一次搜索,因此在对原型对象上做的任何修改都会立即从实例上反映出来,即使是先创建实例后修改原型也是如此:

测试结果:

内存分析:


但是如果在先创建实例后修改原型的情况下,用字面量赋值的方式来重写原型对象,这就会切断现有原型与任何之前存在的对象实例之间的联系(不是先创建实例后修改原型的情况下仍然可以用这种方式重写原型对象)

测试结果:

内存分析:


(图引用《JavaScript高级程序设计第3版》,图中值未改,原理一样)
6、原生对象的模型:
所有原生引用类型(Object、String、Array等)都在其构造函数的原型上定义了方法,例如:Array.prototype.sort()、Array.prototype.substring()等,通过原生对象的模型不仅可以读取到所有默认方法的引用,还可以像修改自定义对象的原型一样修改原生对象的原型,所以也可以给原生对象添加方法,但是在实际运用中我们不要这样去修改原生对象的模型(命名冲突、重写原生方法等等问题都是我们在实际开发中所不希望遇到的)。
7、关于原型对象的几种操作:
1)isPrototypeOf检测实例对象是否包含指向某个原型对象的指针,包含返回true,否则返回false。

2)Object.getPrototypeOf(实例对象),返回的就是这个对象的原型,下面结果为true

Object.getPrototypeOf(person1).name,通过这种方式可以访问原型对象上name的值
3)hasOwnProperty(从Object中继承而来),检测一个属性是否存在于实例中,是就返回true,否则返回false

用 in 也可以检测属性值,只不过用这种方式检测的,无论属性在实例中还是在原型中都会返回true
4)Object.keys(原型对象),返回一个包含所有可枚举属性的字符串数组

测试结果:

8、原型对象的缺点:
原型对象的好处是原型对象上的所有属性和方法可以被很多实例共享,缺点是当原型中包含引用类型的值的属性时,一个实例对象对这个引用类型的的属性做了修改,在其他实例对象中也可以体现:

9、好的实践:
1)组合使用构造函数模式和原型模式

2)动态原型模式


前端知识体系:JavaScript基础-原型和原型链-理解原型设计模式以及 JavaScript中的原型规则的更多相关文章
- web前端知识体系总结
1. 前言 大约在几个月之前,让我看完了<webkit技术内幕>这本书的时候,突然有了一个想法.想把整个web前端开发所需要的知识都之中在一个视图中,形成一个完整的web前端知识体系,目的 ...
- 自己总结的web前端知识体系大全【欢迎补充】
1. 前言 大约在几个月之前,让我看完了<webkit技术内幕>这本书的时候,突然有了一个想法.想把整个web前端开发所需要的知识都之中在一个视图中,形成一个完整的web前端知识体系,目的 ...
- web前端知识体系大全
1. 前言 大约在几个月之前,让我看完了<webkit技术内幕>这本书的时候,突然有了一个想法.想把整个web前端开发所需要的知识都之中在一个视图中,形成一个完整的web前端知识体系,目的 ...
- web前端知识体系小结(转)
1. 前言 大约在几个月之前,让我看完了<webkit技术内幕>这本书的时候,突然有了一个想法.想把整个web前端开发所需要的知识都之中在一个视图中,形成一个完整的web前端知识体系,目的 ...
- Web前端知识体系精简
Web前端技术由html.css和javascript三大部分构成,是一个庞大而复杂的技术体系,其复杂程度不低于任何一门后端语言.而我们在学习它的时候往往是先从某一个点切入,然后不断地接触和学习新的知 ...
- 从输入URL到页面加载的过程?如何由一道题完善自己的前端知识体系!
前言 见解有限,如有描述不当之处,请帮忙指出,如有错误,会及时修正. 为什么要梳理这篇文章? 最近恰好被问到这方面的问题,尝试整理后发现,这道题的覆盖面可以非常广,很适合作为一道承载知识体系的题目. ...
- Web前端知识体系
看到一篇不错的文章,拿来收藏和分享. 原文:http://mp.weixin.qq.com/s/UFTfdE7LYhHquWEzwZKLCQ Web前端技术由html.css和 javascript三 ...
- web前端知识体系大全【欢迎补充】
大约在几个月之前,让我看完了<webkit技术内幕>这本书的时候,突然有了一个想法.想把整个web前端开发所需要的知识都之中在一个视图中,形成一个完整的web前端知识体系,目的是想要颠覆人 ...
- web前端知识体系大全【转载】
自己总结的web前端知识体系大全[欢迎补充] 1. 前言 大约在几个月之前,让我看完了<webkit技术内幕>这本书的时候,突然有了一个想法.想把整个web前端开发所需要的知识都之中在 ...
- WEB前端知识体系脑图
说在开始的话: 我上大学那会,虽说主要是学Java语言,但是web前端也稍微学了一些,那时候对前端也没多在意,因为涉入的不深,可以搞一个差不多可以看的界面就可以了,其他也没过多在意. 因为稍微了解一点 ...
随机推荐
- 《Tsinghua oc mooc》第5~7讲 物理内存管理
资源 OS2018Spring课程资料首页 uCore OS在线实验指导书 ucore实验基准源代码 MOOC OS习题集 OS课堂练习 Piazza问答平台 暂时无法注册 疑问 段式内存管理中,逻辑 ...
- JDBC:数据库连接技术
JDBC :带它再爱你一次 (一) JDBC 入门 (1) 概述 Java数据库连接,(Java Database Connectivity,简称JDBC)是Java语言中用来规范客户端程序如何来访问 ...
- SQL Server事务(二)
事务的四大特性: 1.原子性:原子性是指事务包含的所有操作要么全部成功,要么全部失败回滚,这和前面两篇博客介绍事务的功能是一样的概念,因此事务的操作如果成功就必须要完全应用到数据库,如果操作失败则不能 ...
- idea npm vue java开发工具安装 环境配置
感谢此链接内容作者,从前往后流程较完整详细,助我成功配置好(不知道在这之前做的一些尝试有没有影响) https://blog.csdn.net/qq_42564846/article/details/ ...
- 洛谷 P4198 楼房重建 线段树维护单调栈
P4198 楼房重建 题目链接 https://www.luogu.org/problemnew/show/P4198 题目描述 小A的楼房外有一大片施工工地,工地上有N栋待建的楼房.每天,这片工地上 ...
- Codeforces Round #590 (Div. 3) Editorial
Codeforces Round #590 (Div. 3) Editorial 题目链接 官方题解 不要因为走得太远,就忘记为什么出发! Problem A 题目大意:商店有n件商品,每件商品有不同 ...
- vs code 更改快捷键
选择左下角设置图标,快捷键方式 文件列表修改,搜 list 文件tree list.focusUp -> ctrl+p
- ES6——入门学习指南
ES6的简介: ECMAScript6.0(以下简称ES6)是JavaScript语言的下一代标准,已在2015年6月正式发布了.它的目标,是使得JavaScript语言可以用来编写复杂的大型应用程序 ...
- golang数据类型
整数类型 Golang各整数类型分:有符号和无符号,int uint 的大小和系统有关. Golang查看一个变量的数据类型: package main import "fmt" ...
- Introduction to Deep Learning Algorithms
Introduction to Deep Learning Algorithms See the following article for a recent survey of deep learn ...