js 原型对象和原型链理解
作者:Deja0vu0 发布时间:2024-04-23 09:20:23
一个例子让你彻底明白原型对象和原型链
开篇
之前对js中的原型链和原型对象有所了解,每当别人问我什么是原型链和原型对象时,我总是用很官方(其实自己不懂)的解释去描述。有一句话说的好:如果你不能把一个很复杂的东西用最简单的话语描述出来,那就说明你没有真正的理解。最近正在读《Javascript高级程序设计》,书中对原型对象和原型链的描述让我受益匪浅,下面仅用一个对比性的例子来说明。
我们经常会这么写
function Person () {
this.name = 'John';
}
var person = new Person();
Person.prototype.say = function() {
console.log('Hello,' + this.name);
};
person.say();//Hello,John
上述代码非常简单,Person原型对象定义了公共的say方法,虽然此举在构造实例之后出现,但因为原型方法在调用之前已经声明,因此之后的每个实例将都拥有该方法。从这个简单的例子里,我们可以得出:
原型对象的用途是为每个实例对象存储共享的方法和属性,它仅仅是一个普通对象而已。并且所有的实例是共享同一个原型对象,因此有别于实例方法或属性,原型对象仅有一份。所有就会有如下等式成立:
person.say == new Person().say
可能我们也会这么写
function Person () {
this.name = 'John';
}
var person = new Person();
Person.prototype = {
say: function() {
console.log('Hello,' + this.name);
}
};
person.say();//person.say is not a function
很不幸,person.say方法没有找到,所以报错了。其实这样写的初衷是好的:因为如果想在原型对象上添加更多的属性和方法,我们不得不每次都要写一行Person.prototype,还不如提炼成一个Object来的直接。但是此例子巧就巧在构造实例对象操作是在添加原型方法之前,这样就会造成一个问题:
当var person = new Person()时,Person.prototype为:Person {}(当然了,内部还有constructor属性),即Person.prototype指向一个空的对象{}。而对于实例person而言,其内部有一个原型链指针proto,该指针指向了Person.prototype指向的对象,即{}。接下来重置了Person的原型对象,使其指向了另外一个对象,即
Object {say: function},
这时person.proto的指向还是没有变,它指向的{}对象里面是没有say方法的,因为报错。
从这个现象我们可以得出:
在js中,对象在调用一个方法时会首先在自身里寻找是否有该方法,若没有,则去原型链上去寻找,依次层层递进,这里的原型链就是实例对象的__proto__属性。
若想让上述例子成功运行,最简单有效的方法就是交换构造对象和重置原型对象的顺序,即:
function Person () {
this.name = 'John';
}
Person.prototype = {
say: function() {
console.log('Hello,' + this.name);
}
};
var person = new Person();
person.say();//person.say is not a function
一张图让你秒懂原型链
其实,只需要明白原型对象的结构即可:
Function.prototype = {
constructor : Function,
__proto__ : parent prototype,
some prototype properties: ...
};
总结:函数的原型对象constructor默认指向函数本身,原型对象除了有原型属性外,为了实现继承,还有一个原型链指针__proto__,该指针指向上一层的原型对象,而上一层的原型对象的结构依然类似,这样利用__proto__一直指向Object的原型对象上,而Object的原型对象用Object.__proto__ = null表示原型链的最顶端,如此变形成了javascript的原型链继承,同时也解释了为什么所有的javascript对象都具有Object的基本方法。
来源:http://www.cnblogs.com/dejavu-DL/p/6381727.html
猜你喜欢
- 尽管很多 NoSQL 数据库近几年大放异彩,但是像 MySQL 这样的关系型数据库依然是互联网的主流数据库之一,每个学 Python 的都有
- 所有软件的版本一直会升级,注意自己当时的版本是不是已经更新了。首先装centos7如果你忘了设置swap分区,下面的文章可以教你怎么补一个上
- execute、executeUpdate、executeQuery三者的区别(及返回值)一、boolean execute(String
- 从 gif 直观地感受一下效果我有大量 url 需要访问,但是有些 url 会超时为了避免超时,设置driver.set_page_load
- 1. 查看本机系统及python版本# cat /etc/redhat-release CentOS release 6.7 (Final)
- 1、解决方法(1)忽视元组。缺少类别标签时,通常这样做(假设挖掘任务与分类有关),除非元组有多个属性缺失值,否则该方法不太有效。当个属性缺值
- 用Dreamweaver制作网页时,如果插入的图片、GIF动画、声音、视频或链接的网页是用中文命名的,在用IE浏览器浏览时可能显示不出来。以
- 最近在学习Vue这个框架,发现新的版本中,官网的文档里面说的过渡效果,如果直接粘贴官方的例子中的代码,发现并没有过渡的效果,经过反复测试之后
- 一,原图和效果图二,代码//#########################产生随机颜色#########################
- 测试过程如下:create table sales as select * f
- <%@ Language=VBScript %><%Option Explicit %><%Dim strUR
- 使用torchvision来进行图片的数据增广数据增强就是增强一个已有数据集,使得有更多的多样性。对于图片数据来说,就是改变图片的颜色和形状
- 配置说明Linux系统:CentOS-7.0MySQL版本:5.7.21Linux系统下启动多个MySQL实例,目前知道有两种方法,一种是通
- 散点图什么是散点图?散点图是指在数理统计回归分析中,数据点在直角坐标系平面上的分布图, 散点图表示因变量随自变量而变化的大致趋势,
- 本文实例讲述了mysql事务管理操作。分享给大家供大家参考,具体如下:本文内容:什么是事务管理事务管理操作回滚点默认的事务管理首发日期:20
- 这篇文章主要介绍了python字符串替换re.sub()实例解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值
- 项目介绍采用广度优先搜索方法获取一个网站上的所有外链。首先,我们进入一个网页,获取网页的所有内链和外链,再分别进入内链中,获取该内链的所有内
- 1、有时候我们可能想让字符串倒序输出,下面给出几种方法方法一:通过索引的方法>>> strA = "abcdeg
- 从字符串载入模板我们可以定义模板字符串,然后载入并解析渲染:template.New(tplName string).Parse(tpl s
- 方法一 1.新建一个同名的数据库 2.再停掉sqlserver(注意不要分离数据库) 3.用原数据库的数据文件覆盖掉这个新建的数据库 4.再