js中__proto__和prototype的区别和关系? 这样好理解多了
原型的概念
真正理解什么是原型是学习原型理论的关键。很多人在此产生了混淆,没有真正理解,自然后续疑惑更多。
首先,我们明确原型是一个对象,其次,最重要的是,
Every function has a prototype property and it contains an object
这句话就是说,每个函数都有一个属性叫做原型,这个属性指向一个对象。
也就是说,原型是函数对象的属性,不是所有对象的属性,对象经过构造函数new出来,那么这个new出来的对象的构造函数有一个属性叫原型。明确这一点很重要。
The prototype property is a property that is available to you as soon as you define the function. Its initial value is an "empty" object.
每次你定义一个函数的时候,这个函数的原型属性也就被定义出来了,也就可以使用了,如果不对它进行显示赋值的话,那么它的初始值就是一个空的对象Object。
所以,综上我们知道我们讨论原型的时候,都是基于函数的,有了一个函数对象,就有了原型。切记这一点,讨论原型,不能脱离了函数,它是原型真正归属的地方, 原型只是函数的一个属性 !
function foo(a,b) {
return a+b;
}
foo.prototype
foo.constructor
chrome控制台测试结果
Paste_Image.png
我们可以看到函数foo的原型是空对象Object,所有函数的构造函数都是Function。
使用原型给对象添加方法和属性
不使用原型,使用构造函数给对象添加属性和方法的是通过this,像下面这样。
function Gadget(name, color) {
this.name = name;
this.color = color;
this.whatAreYou = function() {
return 'I am ' + this.color + ' ' + this.name;
}
}
Gadget是一个构造函数,作为一个函数,它有一个属性,这个属性是原型,它指向一个对象,目前我们没有设置这个属性,所以它是一个空的对象。 Adding methods and properties to the prototype property of the constructor function is another way to add functionality to the objects this constructor produces 当我们有了原型之后,我们可以给构造函数的原型对象添加属性和方法来。 像下面这样
Gadget.prototype.price = 100;
Gadget.prototype.rating = 3;
Gadget.prototype.getInfo = function() {
return 'Rating: ' + this.rating +', price: ' + this.price;
}
给原型添加了属性和方法后,原型所指的对象也会更新
Paste_Image.png
使用原型对象的属性和方法
我们使用原型的对象和方法不会在直接在构造函数上使用,而是通过构造函数new出一个对象,那么new出来的对象就会有构造函数原型里的属性和方法。
Paste_Image.png
这里很容易造成误解,我们需要强调newtoy这个new出来的对象是没有原型的,原型只是函数对象的一个属性,newtoy是通过构造函数new出来的对象,所以他不是函数对象,也没有prototype属性,我们在chrome的控制台里自然也无法访问他的prototype属性。 但我们可以通过构造函数访问。 我们知道每个对象都有constructor属性,newtoy的constructor属性就指向Gadget,那么我们通过constructor可以访问到prototype。
Paste_Image.png
到这里,我们对为什么要通过constructor.protptype访问属性应该清楚了。(笔者第一次接触原型就没看懂这个),切记,原型是函数对象的属性,只有函数对象才有原型就容易理解了。
原型的实时性
这里特别需要提出,原型是实时的,意思就是原型对象的属性和方法会实时更新。其实很好理解,javascript中对象是通过引用传递的,原型对象只有一份,不是new出一个对象就复制一份,所以我们对原型的操作和更新,会影响到所有的对象。这就是原型对象的实时性。
Paste_Image.png
自身属性与原型属性
这里涉及到javascript是如何搜索属性和方法的,javascript会先在对象的自身属性里寻找,如果找到了就输出,如果在自身属性里没有找到,那么接着到构造函数的原型属性里去找,如果找到了就输出,如果没找到,就null。 所以,如果碰到了自身属性和原型属性里有同名属性,那么根据javascript寻找属性的过程,显然,如果我们直接访问的话,会得到自身属性里面的值。
Paste_Image.png
我们加下来做一个小实验,寻找toString方法是谁的属性,一步步寻找
Paste_Image.png
通过实验我们可以发现,原来toString方法是object的原型对象的方法。
isPrototypeOf()
Object的原型里还有这样一个方法isPrototypeOf(),这个方法可以返回一个特定的对象是不是另一个对象的原型,实际这里不准确,因为我们知道只有函数对象有原型属性,普通对象通过构造函数new出来,自动继承了构造的函数原型的属性方法。但这个方法是可以直接判断,而不需要先取出constructor对象再访问prototype。看下面的例子:
function Human(name) {
this.name = name;
}
var monkey = {
hair:true,
feeds:'banana',
}
Human.prototype = monkey;
var chi = new Human('chi');
神秘的proto链接
我们之前访问对象的原型,都要先取得构造函数然后访问prototype
chi.constructor.prototype;
newtoy.constructor.prototype;
这样是不是特别别扭,所以各个浏览器一般都会给出一个proto属性,前后分别有双下划线,对象的这个属性可以直接访问到构造函数的原型。这就很方便了。所以proto与prototype是有很大区别的。区别就在此。proto是实例对象用来直接访问构造函数的属性,prototype是函数对象的原型属性。
Paste_Image.png
chi.constructor.prototype == chi.__proto__
Paste_Image.png
显然现在已经很容易弄清楚了proto和prototype的区别了。
原型的陷阱
原型在使用的时候有一个陷阱: 在我们完全替换掉原型对象的时候,原型会失去实时性,同时原型的构造函数属性不可靠,不是理论上应该的值。 这个陷进说的是什么呢?好像不太明白 举个例子我们就懂了
function Dog() {
this.tail = true;
}
var benji = new Dog();
var rusty = new Dog();
Dog.prototype.say = function () {
return 'Woof!';
};
我们进行测试:
Paste_Image.png
直到这里一切都是正常的 接下来我们将原型对象整个替换掉
Dog.prototype = {
paws: 4,
hair: true
};
Paste_Image.png
通过测试我们发现,我们没法访问刚刚更新的原型对象,却能访问之前的原型对象,这说明没有实现实时性。
我们继续测试
Paste_Image.png
我们发现这时新建的对象可以访问更新后的原型,但是构造方法又不对了,本来constructor属性应该指向dog,结果却指向了Object。这就是javascript中的原型陷阱。
我们很容易解决这个问题,只要在更新原型对象后面,重新指定构造函数即可。
Dog.prototype.constructor = Dog;
Paste_Image.png
这样所有就按正常的运行了
所以我们切记在替换掉原型对象之后,切记重新设置constructor.prototype
js中__proto__和prototype的区别和关系? 这样好理解多了的更多相关文章
- js中__proto__和prototype的区别和关系?
_proto__(隐式原型)与prototype(显式原型)1.是什么 显式原型 explicit prototype property: 每一个函数在创建之后都会拥有一个名为prototype的属性 ...
- 理解js中__proto__和prototype的区别和关系
首先,要明确几个点:1.在JS里,万物皆对象.方法(Function)是对象,方法的原型(Function.prototype)是对象.因此,它们都会具有对象共有的特点.即:对象具有属性__proto ...
- [转载]js中__proto__和prototype的区别和关系
首先,要明确几个点:1.在JS里,万物皆对象.方法(Function)是对象,方法的原型(Function.prototype)是对象.因此,它们都会具有对象共有的特点.即:对象具有属性_ ...
- js中__proto__和prototype的区别和关系
首先,要明确几个点:1.在JS里,万物皆对象.方法(Function)是对象,方法的原型(Function.prototype)是对象.因此,它们都会具有对象共有的特点.即:对象具有属性_ ...
- (转)js中__proto__和prototype的区别和关系
作者:doris链接:https://www.zhihu.com/question/34183746/answer/58155878来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业转载请 ...
- js中__proto__和prototype的区别和关系?(转)
转自知乎:https://www.zhihu.com/question/34183746
- js中__proto__, property, prototype, 对象自身属性方法和原型中的属性方法的区别
__proto__: 这个属性是实例对象的属性,每个实例对象都有一个__proto__属性,这个属性指向实例化该实例的构造函数的原型对象(prototype). proterty:这个方法是对象的属性 ...
- 说一说js中__proto__和prototype以及原型继承的那些事
在面试中遇到过,问js如何实现继承,其实最好的方式就是构造函数+原型,今天在讨论中,发现自己以前理解上的一些误区,特地写出来,最近都比较忙,等手上的项目做完,可以来做个总结. 先说我以前没有认识到位的 ...
- js中 __proto__ 和 prototype
js中的对象都有__proto__属性存在[隐式原型],注意是两个_, 1,javascript对象的__proto__指向的是该对象的构造函数的原型对象,即constructor.prototype ...
随机推荐
- JavaWeb总结(五)
使用Servlet接受服务器请求信息 HTTP请求示例 HttpServletRequest对象主要用于获取由客户端发送过来的请求头.参数.文件.数据等.Servlet存在的主要目的就是处理请求.Se ...
- 英语linux+英语firefox+英语Oracle OEM如何设置成显示日语
1 linux安装盘挂载,安装日语语言包 2 linux的系统语言设置为日语 3 firefox的 edit-> setting -> contents -> language se ...
- CF 1138 E. Museums Tour
E. Museums Tour 链接 分析: 按时间建出分层图,每个点形如(u,t),表示u在在t个时刻的点,tarjan缩点.每个强连通分量中的点都能经过,然后DAG上dp. 代码: #includ ...
- 【CJOJ2433】陌上花开 树状数组套替罪羊树
[CJOJ2433]陌上花开 树状数组套替罪羊树 蛤?bzoj?没权限QAQ 蛤?CDQ?看了好久没看懂QwQ 好吧我会拿cdq再写一遍的 为啥我感觉这东西比cdq好写 只好拿树状数组套替罪羊树水水了 ...
- MySQL数据库查询某个库下有几张数据表
如果统计某数据库中存在多少张数据表,使用如下SQL检索语句即可: SELECT COUNT(*) TABLES, table_schema FROM information_schema.TABLES ...
- python游戏编程——乌龟和鱼类场景编程
综合举例: 游戏编程:按以下要求定义一个乌龟类和鱼类并尝试编写游戏. O 假设游戏场景为范围(x, y)为0<=x<=10,0<=y<=10 · 游戏生成1只 ...
- TPO-20-Apply for the undergraduate research fund
/* 加粗:语音部分 * 红色:单词部分 * 斜体:语法部分 * 下划线:信号词/句 */ 第 1 段 1.Listen to a conversation between a ...
- NO 18---- webpack 4.x 使用遇到的问题以及开发配置
最近在项目中用webpack的过程中老是出现问题,很是纳闷,按理说一直这样使用没有问题啊,经过我研究后发现,是因为在webpack更新到4.x之后,操作方式与之前相比变化很大.而我们使用npm默认安装 ...
- leetcode刷题笔记191 位1的个数
题目描述: 编写一个函数,输入是一个无符号整数,返回其二进制表达式中数字位数为 ‘1’ 的个数(也被称为汉明重量). 示例: 输入: 输出: 解释: 32位整数 的二进制表示为 . 题目分析: 判断3 ...
- window搭建私有云,只要几分钟
本文介绍如何在window搭建私有云网盘. 工具/原料:一台window系统电脑或者window服务器(vps),Xampp 安装包,可道云kodexplorer安装包 第一步,xampp安装 1.官 ...