理解原型设计模式以及 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中的原型规则的更多相关文章

  1. web前端知识体系总结

    1. 前言 大约在几个月之前,让我看完了<webkit技术内幕>这本书的时候,突然有了一个想法.想把整个web前端开发所需要的知识都之中在一个视图中,形成一个完整的web前端知识体系,目的 ...

  2. 自己总结的web前端知识体系大全【欢迎补充】

    1. 前言 大约在几个月之前,让我看完了<webkit技术内幕>这本书的时候,突然有了一个想法.想把整个web前端开发所需要的知识都之中在一个视图中,形成一个完整的web前端知识体系,目的 ...

  3. web前端知识体系大全

    1. 前言 大约在几个月之前,让我看完了<webkit技术内幕>这本书的时候,突然有了一个想法.想把整个web前端开发所需要的知识都之中在一个视图中,形成一个完整的web前端知识体系,目的 ...

  4. web前端知识体系小结(转)

    1. 前言 大约在几个月之前,让我看完了<webkit技术内幕>这本书的时候,突然有了一个想法.想把整个web前端开发所需要的知识都之中在一个视图中,形成一个完整的web前端知识体系,目的 ...

  5. Web前端知识体系精简

    Web前端技术由html.css和javascript三大部分构成,是一个庞大而复杂的技术体系,其复杂程度不低于任何一门后端语言.而我们在学习它的时候往往是先从某一个点切入,然后不断地接触和学习新的知 ...

  6. 从输入URL到页面加载的过程?如何由一道题完善自己的前端知识体系!

    前言 见解有限,如有描述不当之处,请帮忙指出,如有错误,会及时修正. 为什么要梳理这篇文章? 最近恰好被问到这方面的问题,尝试整理后发现,这道题的覆盖面可以非常广,很适合作为一道承载知识体系的题目. ...

  7. Web前端知识体系

    看到一篇不错的文章,拿来收藏和分享. 原文:http://mp.weixin.qq.com/s/UFTfdE7LYhHquWEzwZKLCQ Web前端技术由html.css和 javascript三 ...

  8. web前端知识体系大全【欢迎补充】

    大约在几个月之前,让我看完了<webkit技术内幕>这本书的时候,突然有了一个想法.想把整个web前端开发所需要的知识都之中在一个视图中,形成一个完整的web前端知识体系,目的是想要颠覆人 ...

  9. web前端知识体系大全【转载】

    自己总结的web前端知识体系大全[欢迎补充]   1. 前言 大约在几个月之前,让我看完了<webkit技术内幕>这本书的时候,突然有了一个想法.想把整个web前端开发所需要的知识都之中在 ...

  10. WEB前端知识体系脑图

    说在开始的话: 我上大学那会,虽说主要是学Java语言,但是web前端也稍微学了一些,那时候对前端也没多在意,因为涉入的不深,可以搞一个差不多可以看的界面就可以了,其他也没过多在意. 因为稍微了解一点 ...

随机推荐

  1. java 面试题汇总

    一.Java 基础 1.JDK 和 JRE 有什么区别? JDK是java开发工具包,提供java的开发环境和运行环境.包括编译器.开发工具和更多的类库等.JDK包含了JRE. JRE是java运行环 ...

  2. yum源 epel源 替换及安装

    #!/bin/sh # 备份yum源 zip -r /etc/yum.repos.d/yum_resource_back_up.zip /etc/yum.repos.d/* # 替换yum源 wget ...

  3. 【转帖】sysbench压力测试工具简介

    sysbench压力测试工具简介 https://www.cnblogs.com/pdlife/p/6698957.html 一.sysbench压力测试工具简介: sysbench是一个开源的.模块 ...

  4. 常见的几种web攻击

    1. SQL注入 2. OS命令注入 3. 跨站脚本攻击(XSS) 4. HTTP首部注入 5. 会话劫持 6. 跨站点请求伪造(CSRF) 7. 点击劫持 8. DoS

  5. idea配置glassFish启动项目

    将项目打成war包形式. 然后配置glassFish +号配置启动包 此处配置启动路径 ........ 路径也可以在localhost:4848 --->中的Applicaton中去配置

  6. django的admin密码忘记了怎么办?一分钟解决!!

    django-admin确实是在实际开发中很方便,然后项目开发一段时间放到一边,等你再去玩你当初的项目的时候,可能抱歉你的admin密码忘记了,其实解决办法有很多种,我直说最快的一种,直接重新建立一个 ...

  7. 【AC自动机】Censoring

    [题目链接] https://loj.ac/problem/10059 [题意] 有一个长度不超过  1e5 的字符串 .Farmer John 希望在 T 中删掉 n 个屏蔽词(一个屏蔽词可能出现多 ...

  8. Vue路由传参及传参后刷新导致参数消失处理

    项目功能需要,要从列表页跳转到第三方提供的URL上(这里第三方页面我是通过iframe引入在详情页,目的是点击返回时可以通过keepAlive让列表页不刷新,如果不通过iframe直接跳第三方链接,那 ...

  9. 不吹不黑,赞一下应用运维管理的cassacdra

    不吹不黑的为菊厂的应用运维管理AOM点个赞.Why? 某菊厂应用运维管理工具AOM每天处理着亿级条数据,这么多数据是怎么存储的呢? 说到数据存储就会想到关系型数据库,比如mysql,oracle,sy ...

  10. Jmeter4.0---- jmeter中写入java代码_简单了解(15)

    1.说明 BeanShell:是一个小型嵌入式Java源代码解释器,具有对象脚本语言特性,能够动态地执行标准JAVA语法,并利用在JavaScript和Perl中常见的的松散类型.命令.闭包等通用脚本 ...