Javascript之深入浅出prototype


Posted in Javascript onFebruary 06, 2017

我们先来讲一个故事,一个大大的池塘,里面有很多鱼。这是属于我们大家的池塘所以里面的鱼我们都可以吃,但是我们也会从集市买一些鱼放在家里,那么放在家里的鱼肯定是属于我们私人的,外人是不会拥有的。那么在js里我们就把这个池塘称为原型对象,池塘里面我们所共享的鱼称为原型中的属性及方法,而我们自己的鱼称为构造函数中的属性及方法,我们是什么呢?对了,我们是对象的实例

以上是为了让大家能够趣味性的对prototype有一个概念,接下来就通过代码具体总结一下prototype~

一、理解prototype

我们创建的每一个函数都有一个prototype属性,这个属性是一个指向对象的指针。

构建对象中有一种模式叫做原型模式,意思是将对象实例所不可共享的属性及方法定义在构造函数中,而将可共享的属性及方法放在原型对象中,也就是prototype指向的对象中。以下是用原型模式创建的一个对象:

function person(name, age) {
 this.name = name;
 this.age = age;
}
person.prototype = {
 sayName: function() {
 console.log(this.name); 
 }
};
var p1 = new person("Wind", 20);
p1.sayName(); // "Wind"
var p2 = new person("Nic", 20);
p2.sayName(); // Nic

这里我将name、age属性定义在构造函数中,将sayName方法定义在原型中。所以p1和p2对象实例的内存空间里面各有一份name和age,但是它们却共享一份sayName方法,意思是它们调用的sayName方法是同一个。

试想如果我们不用prototype,而是直接将sayName写进构造函数呢?

那么p1和p2中将各有一份sayName,这样浪费内存空间,所以用prototype的好处之一:提高了代码的复用性,减少内存

在了解原型对象的同时我们还有一个小知识要明白:每当代码读取一个对象属性的时候会执行一次搜索,搜索目标是给定名字的属性,搜索路径为:

对象实例本身---->原型对象---->对象所继承的父类对象---->父类对象原型...---->原型链末端

二、prototype的注意点

1、不可变性:尽管prototype是共享的,但不能通过对象实例重写原型中的值,但是可以由对象统一改。通俗一点:只能爸爸统一改,不能儿子改。(这也和类型有关系,孩子不能改变基本类型的值,但是可以改变对象,比如数组)

基本类型:

function person() {}
person.prototype = { 
 num: 0
}; 
var p1 = new person(); 
var p2 = new person();
p1.num++;
p2.num; // 0

非基本类型:

function person() {}
person.prototype = {
 num: [1,2,3]
}; 
var p1 = new person(); 
var p2 = new person();
p1.num[2] = 8; 
p2.num; // [1, 2, 8] 改变了

2、同名覆盖性:如果我们在实例中添加了一个与原型属性同名的属性,那么该属性会创建到对象实例中并且会覆盖掉原型中的相应属性。

function person(name) {
 this.name = name; 
}
person.prototype = {
 age: 18 9 };
var p1 = new person("Wind");
var p2 = new person("Nic");
p1.age = 20;
p1.age; // 20
p2.age; // 18

3、使用对象字面量创建原型方法,会切断之前的链而重写原型链

function person(name) {
 this.name = name; 
}
person.prototype = { 
 sayName: function() {
 console.log(this.name); 
 }
};
var p1 = new person("Wind");
person.prototype = {
 age = 20
}; 
p1.sayName(); // error

因为prototype指针指向了一个新的对象,切断了构造函数与之前的prototype旧对象的联系,所以p1不能调用了它。那么p1调用新对象的属性呢?

p1.age; // error

所以我做了一个大胆的猜测,就是以前包含sayName的旧对象被“抛弃”了,也就是被内存回收了,然而p1的prototype指针指向的依旧是旧对象,所以会产生error。

三、总结

 prototype的用法:构造函数模型用于定义实例的属性,而原型模型用于定义方法和共享的属性。

以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,同时也希望多多支持三水点靠木!

Javascript 相关文章推荐
boxy基于jquery的弹出层对话框插件扩展应用 弹出层选择器
Nov 21 Javascript
让人印象深刻的10个jQuery手风琴效果应用
May 08 Javascript
js实现拉伸拖动iframe的具体代码
Aug 03 Javascript
用jquery统计子菜单的条数示例代码
Oct 18 Javascript
jQuery 获取、设置HTML或TEXT内容的两种方法
May 23 Javascript
jquery获取radio值实例
Oct 16 Javascript
node.js+express制作网页计算器
Jan 17 Javascript
如何在JS中实现相互转换XML和JSON
Jul 19 Javascript
Html5 js实现手风琴效果
Apr 17 Javascript
AugularJS从入门到实践(必看篇)
Jul 10 Javascript
浅谈Vue SPA 首屏加载优化实践
Dec 15 Javascript
解决React在安装antd之后出现的Can't resolve './locale'问题(推荐)
May 03 Javascript
浅析jsopn跨域请求原理及cors(跨域资源共享)的完美解决方法
Feb 06 #Javascript
canvas实现图像布局填充功能
Feb 06 #Javascript
canvas实现图像截取功能
Feb 06 #Javascript
JS跨域请求外部服务器的资源
Feb 06 #Javascript
canvas实现动态小球重叠效果
Feb 06 #Javascript
canvas滤镜效果实现代码
Feb 06 #Javascript
canvas实现图像放大镜
Feb 06 #Javascript
You might like
星际流派综述
2020/03/04 星际争霸
PHP - Html Transfer Code
2006/10/09 PHP
php代码优化及php相关问题总结
2006/10/09 PHP
基于PHP的cURL快速入门教程 (小偷采集程序)
2011/06/02 PHP
php 获取今日、昨日、上周、本月的起始时间戳和结束时间戳的方法
2013/09/28 PHP
ThinkPHP之getField详解
2014/06/20 PHP
PHP开发框架kohana3 自定义路由设置示例
2014/07/14 PHP
PHP简单实现生成txt文件到指定目录的方法
2016/04/25 PHP
浅析Laravel5中队列的配置及使用
2016/08/04 PHP
PHP实现二叉树深度优先遍历(前序、中序、后序)和广度优先遍历(层次)实例详解
2018/04/20 PHP
在laravel-admin中列表中禁止某行编辑、删除的方法
2019/10/03 PHP
PHP unset函数原理及使用方法解析
2020/08/14 PHP
JavaScript Undefined,Null类型和NaN值区别
2008/10/22 Javascript
解决iframe的frameborder在chrome/ff/ie下的差异
2010/08/12 Javascript
jQuery实现鼠标滚轮动态改变样式或效果
2015/01/05 Javascript
jQuery animate和CSS3相结合实现缓动追逐效果附源码下载
2016/04/18 Javascript
jQuery实现iframe父窗体和子窗体的相互调用
2016/06/17 Javascript
JavaScript面向对象精要(下部)
2017/09/12 Javascript
使用mock.js随机数据和使用express输出json接口的实现方法
2018/01/07 Javascript
深入理解react-router 路由的实现原理
2018/09/26 Javascript
ES6知识点整理之函数数组参数的默认值及其解构应用示例
2019/04/17 Javascript
js中offset,client , scroll 三大元素知识点总结
2019/09/11 Javascript
js全屏事件fullscreenchange 实现全屏、退出全屏操作
2019/09/17 Javascript
[01:05:24]Ti4 冒泡赛第二天 iG vs NEWBEE 3
2014/07/15 DOTA
[49:05]OG vs Newbee 2019DOTA2国际邀请赛淘汰赛 胜者组 BO3 第二场 8.21.mp4
2020/07/19 DOTA
[46:58]完美世界DOTA2联赛PWL S3 Forest vs LBZS 第一场 12.17
2020/12/19 DOTA
pandas创建DataFrame的7种方法小结
2020/06/14 Python
C++:memset ,memcpy和strcpy的根本区别
2013/04/27 面试题
不同浏览器创建XMLHttpRequest方法有什么不同
2014/11/17 面试题
基层干部十八大感言
2014/01/19 职场文书
摄影助理岗位职责
2014/02/07 职场文书
模具专业毕业生自荐书范文
2014/02/19 职场文书
小学教育见习报告
2014/10/31 职场文书
在酒桌上的敬酒词
2015/08/12 职场文书
创业计划书之珠宝饰品
2019/08/26 职场文书
Win10系统下配置Java环境变量
2021/06/13 Java/Android