深入理解JavaScript原型链

前言

最近碰到一个题,大家可以试下。

Object.prototype.a = function() {
    console.log("aaa "+this.name);
};

Function.prototype.b = function() {
    console.log("bbb "+this.name);
};

function Person(name) {
    this.name = name;
}

var person = new Person("China");

问:person.a() person.b()分别返回什么?


资料引用

上述题目考察的是JavaScript原型链的问题。我们引用《JavaScript高级程序设计(第三版)》中关于原型对象的相关叙述。

- 列表内容

无论什么时候,只要创建了一个新函数,就会根据一组特定的规则为该函数创建一个prototype属性,这个属性指向函数的原型对象。

当调用构造函数创建一个新实例后,该实例的内部将包含一个指针(内部属性),指向构造函数的原型对象。ECMA-262第5版中管这个指针叫[[Prototype]]。脚本中没有标准的方式访问[[Prototype]],但浏览器在每个对象上都支持一个属性__proto__。该连接存在于实例与构造函数的原型对象之间,而不是存在于实例与构造函数之间。

分析问题

通过上面的说明,我们再来看下那个题目。构造函数Person有个prototype属性,指向Person的原型对象。而Person.prototype也是一个对象,则内部有[[Prototype]]指针,指向构造函数的原型对象,而该对象的构造函数则是Object()。Person.prototype.__proto__ -----> Object.prototype。而实例person的内部指针[[Prototype]]则指向构造函数Person的原型Person.prototype。

解决问题

通过上面的分析,我们就构造了一条原型链:

person.\__ptoto__ -----> Person.prototype

所以person.a()通过原型链查找,最终找到Object.prototype中的方法a,控制台输出aaa China,而没有找到方法b,所以会报错,显示TypeError: undefined is not a function

深入理解

在问题中,构造函数Person同样也是Function的一个实例,所以Person.__proto__ —–> Function.prototype。而构造函数继承的是Prerson.prototype,而不是Person.\__proto__。

可以通过isPrototypeOf()确定某个对象是否是另一个对象的原型。

Person.prototype.isPrototypeOf(person); //true

另外,ECMA5增加了一个方法Object.getPrototypeOf()来代替__proto__,返回[[Prototype]]的值。

对于操作符instanceof,判断某个对象是否属于某个构造函数,就是通过判断该构造函数的prototype属性是否存在对象的原型链上。

Person instanceof Function; //true

而虽然Object.getPrototypeOf(Function)返回结果是function Empty(){},但

Function instanceof Object仍然返回true,则只能算是甲鱼的臀部——规定啦。

另外,ECMA5提供了一个继承方法Object.create(proto, [ propertiesObject ]),创建一个拥有指定原型和若干个指定属性的对象。

// 只继承Person.prototype 而不实例化name属性
var person = Object.create(Person.prototype);

//但下面仍为true
person instanceof Person;

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-10-13 11:56:55

深入理解JavaScript原型链的相关文章

好文要顶之 --- 简单粗暴地理解 JavaScript 原型链

原型链理解起来有点绕了,网上资料也是很多,每次晚上睡不着的时候总喜欢在网上找点原型链和闭包的文章看,效果极好. 不要纠结于那一堆术语了,那除了让你脑筋拧成麻花,真的不能帮你什么.简单粗暴点看原型链吧,想点与代码无关的事,比如人.妖以及人妖. 1)人是人他妈生的,妖是妖他妈生的.人和妖都是对象实例,而人他妈和妖他妈就是原型.原型也是对象,叫原型对象. 2)人他妈和人他爸啪啪啪能生出一堆人宝宝.妖他妈和妖他爸啪啪啪能生出一堆妖宝宝,啪啪啪就是构造函数,俗称造人. 3)人他妈会记录啪啪啪的信息,所以可

简单粗暴地理解 JavaScript 原型链

尼玛!你特么也是够了! Don’t BB! Show me the code! function Person (name) { this.name = name; } function Mother () { } Mother.prototype = { //Mother的原型 age: 18, home: ['Beijing', 'Shanghai'] }; Person.prototype = new Mother(); //Person的原型为Mother //用chrome调试工具查看

深入理解javascript原型和闭包(转)

深入理解javascript原型和闭包(完结) 说明: 该教程绕开了javascript的一些基本的语法知识,直接讲解javascript中最难理解的两个部分,也是和其他主流面向对象语言区别最大的两个部分——原型和闭包,当然,肯定少不了原型链和作用域链.帮你揭开javascript最神秘的面纱. 为什么要偏偏要讲这两个知识点? 这是我在这么多年学习javascript的经历中,认为最难理解.最常犯错的地方,学习这两个知识点,会让你对javascript有更深层次的理解,至少理解了原型和作用域,就

理解javascript原型和作用域系列 - 目录【连载中...】

说明: 该教程绕开了javascript的一些基本的语法知识,直接讲解javascript中最难理解的两个部分,也是和其他主流面向对象语言区别最大的两个部分——原型和作用域,当然,肯定少不了原型链和作用域链.帮你揭开javascript最神秘的面纱. 为什么要偏偏要讲这两个知识点? 这是我在这么多年学习javascript的经历中,认为最难理解.最常犯错的地方,学习这两个知识点,会让你对javascript有更深层次的理解,至少理解了原型和作用域,就不能再算是javascript菜鸟了.另外,这

【深入理解javascript原型和闭包系列 】 历时半月完稿,求推荐

从下面目录中可以看到,本系列有16篇文章,外加两篇后补的,一共18篇文章.写了半个月,从9月17号开始写的.每篇文章更新时,读者的反馈还是可以的,虽然不至于上头条,但是也算是中规中矩,有看的人,也有评论的人.特别是在后期讲闭包的时候. 我从来都不做基础入门教程,因为基础入门的教程,要想讲的和别人不一样很难.所以,基础入门的教程网上有的是,大家随便搜索就是了,再大不了就花钱买本书看看.而想原型和闭包这类的稍微高级一些的教程,仔细想想,还真的有的讲,真的能讲出自己的思路. 我觉得只要是自己埋头要做的

理解javascript原型和作用域系列(6)——继承

为何用“继承”为标题,而不用“原型链”? 原型链如果解释清楚了很容易理解,不会与常用的java/C#产生混淆.而“继承”确实常用面向对象语言中最基本的概念,但是java中的继承与javascript中的继承又完全是两回事儿.因此,这里把“继承”着重拿出来,就为了体现这个不同. javascript中的继承是通过原型链来体现的.先看几句代码 以上代码中,f1是Foo函数new出来的对象,f1.a是f1对象的基本属性,f1.b是怎么来的呢?——从Foo.prototype得来,因为f1.__prot

轻松搞定javascript原型链 _proto_

//如有错误或不同观点,欢迎批评与讨论!首先,prototype出现的目的,是为了解决 代码重用 的问题 , prototype 相当于是在内存上划分出一个公共的区域, 专用于存放 实例化对象 的相同方法或属性, 一份代码,人人可用:为方便理解,我们可以先把prototype 当作是CSS中的 class,在prototype上加方法和属性,那么其它对象就会拥有这些方法和属性, 但这些代码紧有一份!<script>function Person(){this.name = '张三'; this

深入理解javascript原型和闭包(17)——补this

本文对<深入理解javascript原型和闭包(10)——this>一篇进行补充,原文链接:http://www.cnblogs.com/wangfupeng1988/p/3988422.html 原文中,讲解了在javascript中this的各个情况,写完之后发现还落下一种情况,就此补充. 原文中this的其中一种情况是构造函数的,具体的内容可以参考原文,此处不再赘述. 要补充的内容是,在构造函数的prototype中,this代表着什么. 如上代码,在Fn.prototype.getNa

深入理解javascript原型和闭包 (转)

该教程绕开了javascript的一些基本的语法知识,直接讲解javascript中最难理解的两个部分,也是和其他主流面向对象语言区别最大的两个部分——原型和闭包,当然,肯定少不了原型链和作用域链.帮你揭开javascript最神秘的面纱. 为什么要偏偏要讲这两个知识点? 这是我在这么多年学习javascript的经历中,认为最难理解.最常犯错的地方,学习这两个知识点,会让你对javascript有更深层次的理解,至少理解了原型和作用域,就不能再算是javascript菜鸟了.另外,这两方面也是