前端知识体系: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前端也稍微学了一些,那时候对前端也没多在意,因为涉入的不深,可以搞一个差不多可以看的界面就可以了,其他也没过多在意. 因为稍微了解一点 ...
随机推荐
- oracle - for in loop 循环更新
用法:目的更新B表的数据 查询出A表的字段,命名为表1.然后更新B表 BEGIN FOR 表1 IN ( SELECT [匹配字段],[更新字段] FROM A表 ) loop UPDATE B表 S ...
- SpringBoot起步
1.SpringBoot依赖包导入 方式一:将spring-boot的依赖为父pom出现 <parent> <groupId>org.springframework.boot& ...
- ios 输入框失去焦点,位置回调方法
微信网页开发,ios 在input,textarea 失去焦点后,页面无法回调. 以下方法可解决: $("input,textarea").on("blur", ...
- MyBatis 源码篇-日志模块2
上一章的案例,配置日志级别为 debug,执行一个简单的查询操作,会将 JDBC 操作打印出来.本章通过 MyBatis 日志部分源码分析它是如何实现日志打印的. 在 MyBatis 的日志模块中有一 ...
- C#端口、IP正则
端口正则: string pattrn = "^[0-9]+$"; if (System.Text.RegularExpressions.Regex.IsMatch(Porttex ...
- javaIO——概述
以前看java书,都将IO作为一个大的章节甚至模块来编写,可见IO在java语言中的重要性. java的流按功能和处理的目标数据不同可以分为字节流和字符流.字符流处理的基本数据单元是字符:字节流处理的 ...
- Spark读取HDFS文件,任务本地化(NODE_LOCAL)
Spark也有数据本地化的概念(Data Locality),这和MapReduce的Local Task差不多,如果读取HDFS文件,Spark则会根据数据的存储位置,分配离数据存储最近的Execu ...
- js之数据类型(对象类型——构造器对象——日期)
Date对象是js语言中内置的数据类型,用于提供日期与时间的相关操作.学习它之前我们先了解一下什么是GMT,什么时UTC等相关的知识. GMT: 格林尼治标准时间(Greenwich Mean Tim ...
- 垃圾分类常见APP
垃圾分类指南app 上海就要实行垃圾分类了,垃圾分类指南app你需要吗,这里有相关的各种垃圾分类的介绍与上海垃圾分类投放指南,这里是垃圾分类指南手机入口能够让你更好的去完成垃圾分类呢.垃圾分类指 .. ...
- **表示python中的意思
**表示python中的意思 **表示python中的电源操作传递参数和定义参数时(所谓的参数是调用函数时传入的参数,参数是定义函数时定义函数的参数),还可以使用两个特殊语法:“`*`**”. 调用函 ...