博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
javascript的设计模式(三)———— 原型模式
阅读量:4655 次
发布时间:2019-06-09

本文共 1886 字,大约阅读时间需要 6 分钟。

原型模式在js中经常用来创建对象的一种模式,它并不是通过创建类来创建对象,而是通过克隆一个对象来创建对象。在js中没有类的概念,所以js中的面向对象编程方式基本都是使用原型模式实现的。

正文

1.原型对象

function Person(){};Person.prototype.name = 'Marys';
以上代码声明了一个新函数Preson,每一个新函数里都包含一个prototype属性(这是一个指针),这个属性指向一个对象,这就是 "原型对象",这个对象包含构建该函数的一切属性和方法,其中包含一个constructor属性,该属性指向函数本身。如下图所示

1105247-20171129173627565-867232908.png

var person1 = new Person();
上面的代码中,person1声明为Person的实例,在类语言中就可以说,person1是Person类型,就像数字 1 是Number类型一样。但是js中没有类的概念,那么js是怎么实例化一个对象的呢?首先,当一个实例对象被声明,该实例便会包含一个[[prototype]]属性(这是也一个指针),在一些浏览器中,他可以用 __proto__ 属性名读取到;然后,这个[[prototype]]属性会指向他的父级的原型对象————prototype,换句话说prototype也是person1的原型对象。关系如下图所示。

1105247-20171129173734815-987900628.png

1.1 原型链

1105247-20171129173750644-1341084293.png

如上图,便是在chrome中打印person1的结果。可以看到,在person1下的 __proto__ 属性展开后是Person的原型,其中也包含一个 __proto__ 属性,这个原型便是指向最根部的Object原型。像这样一层包一层的结构就像是一条链子,把原型一个个连接起来,这就是原型链。当要调用一个对象或一个方法的时候,在创建的实例中找不到的话,js便会沿着这条原型链一直向下找,如果原型链中都找不到,就是undefined了。如下面的代码,打印出来的是Person中定义的Marys

function Person(){};Person.prototype.name = 'Marys';var person1 = new Person();console.log(person1.name);

1.2 关于this

this的指向是根据**执行上下文(作用域)**决定的,是一个由构造函数constructor创建的对象,所以this中的属性方法并不存在原型对象中。具体this的变化过程如下:
  • 创建实例对象
  • 将作用域赋予对象(因此this就指向了新对象)
  • 执行构造函数中的代码,为实例对象添加属性和方法

小结

js中的原型模式实际上就是用来实现继承的一种方式,但是使用原型模式继承的属性和方法都有一个缺点:对于引用类型值得属性是会共用的。也就是说继承的属性如果是引用类型值不是独立的,当改变其中一个实例的属性值时,其他同父级的实例的该属性也是会改变。如下代码,当person1的numbers属性推入一个值,person2中的numbers值也会受影响。但是如果代码是person1.numbers = [1,2,3],person2的numbers属性是不会受到影响的,因为这样相当于person1声明了一个新的属性numbers,这是属于person1自己的属性,用this关键字是能读取到的,当声明属性与__proto__中的属性重名的时候,会遮挡原型对象中的属性。

function Person(){};Person.prototype.numbers = [1,2,3,4];var person1 = new Person();var person2 = new Person();person1.numbers.push(5);console.log(person2.numbers);//[1,2,3,4,5]person1.numbers = [1,2,3];console.log(person2.numbers);//[1,2,3,4,5]console.log(person1);/*Person {numbers: Array(3)}  numbers:(3) [1, 2, 3]  __proto__:    numbers:(5) [1, 2, 3, 4, 5]    constructor:ƒ Person()    __proto__:Object*/

转载于:https://www.cnblogs.com/Marys/p/7921789.html

你可能感兴趣的文章
开源控Meteor的个人资料
查看>>
kafka在zookeeper中的存储结构
查看>>
linux上FTP服务器搭建
查看>>
hdu 1506 Largest Rectangle in a Histogram dp
查看>>
华为机试测试-dna-字符串
查看>>
JSON序列化和解析
查看>>
20150221—LINQ to SQL 查询数据
查看>>
asp.net Mvc 访问静态页面
查看>>
数据结构和算法 — 平衡二叉树的实现
查看>>
帝国CMS判断会员是否登录及登录后才能看到内容的方法
查看>>
使用三大框架实现文件的上传及下载
查看>>
理解 HTTP2.0
查看>>
小米手机安装mitmproxy证书
查看>>
简要分析webpack打包后代码
查看>>
js中级第四天
查看>>
mysql 指令
查看>>
【转载】COM 组件设计与应用(六)——用 ATL 写第一个组件
查看>>
使用python处理文件
查看>>
语法制导翻译——语义分析
查看>>
Android中自定义实现高德地图图层效果的源码
查看>>