【JS】中的原型prototype到底是个啥
一、什么是原型
原型prototype是函数的一个属性,这个属性是一个指针,指向一个对象(原型对象),这个原型对象的用途是包含可以由特定类型的所有实例共享的属性和方法。
函数也是一种对象。它也是属性的集合,你也可以对函数进行自定义属性。
javascript就默认的给函数一个属性——prototype。所以,每个函数都有一个属性叫做prototype。
这个prototype的属性值是一个对象(属性的集合!),默认的只有一个叫做constructor的属性,指向这个函数本身。
原型既然作为对象,属性的集合,肯定可以自定义的增加许多属性。例如Object的prototype里面,就有好几个其他属性。

那么看着上图想象一下:
1、我们先创建了一个Person函数备用。
var Person = function(name,age){
this.name = name;
this.age = age;
}
2、Person函数本身也是一个对象,它具有一个属性prototype。
这个属性prototype也是一个对象,它具有一些属性集合。其中有一个属性constructor是一个指针,指向Person函数对象。
那么,此时在内存中,Person及其属性prototype都是唯一一份的单实例。
3、然后,我们利用Person函数new两个对象p1、p2。
这时候,对象p1、p2除了name和age之外,还会默认携带一个隐藏属性__proto__,它是一个指针,指向全局的Person的prototype属性。
二、原型有什么用处
仍然考虑上面的Person函数,现在需要添加一个函数:
var Person = function(name,age){
this.name = name;
this.age = age;
this.isAdult = function(){
if(this.age >= 18){
return true;
}else{
return false;
}
}
}
如果按照上述写法,每一次new Person的时候都会创建一个isAdult的实例。
打印表达式(p1.isAdult===p2.isAdult)的结果,显示为false。显然,这不是我们想要的。
可以这样做:
var Person = function(name,age){
this.name = name;
this.age = age;
}
Person.prototype.isAdult = function(){
if(this.age >= 18){
return true;
}else{
return false;
}
}
由于所有对象的__proto__属性,都是指向全局唯一的Person的属性prototype。
所以,所有由Person创建出来的对象都会共用一个isAdult()方法的实例,类似于Java中的static类型的方法(类方法)。
由此可见,通过这种方式,可以向已定义的对象追加方法。
所以有如下结论:
1、把方法写在prototype中比写在构造函数中消耗的内存更小,因为在内存中一个类的原型只有一个,写在原型中的行为可以被所有实例共享,
实例化的时候并不会在实例的内存中再复制一份 而写在类中的方法,实例化的时候会在每个实例中再复制一份,所以消耗的内存更高
所以没有特殊原因,我们一般把属性写到类中,而行为写到原型中。
2、构造函数中定义的属性和方法要比原型中定义的属性和方法的优先级高,如果定义了同名称的属性和方法,构造函数中的将会覆盖原型中的。
【JS】中的原型prototype到底是个啥的更多相关文章
- js中的原型prototype
var arr1 = new Array(12,34,98,43,38,79,56,1); arr1.sum=function (){ var result = 0; for(var i=0; i&l ...
- JS 中的原型 -- prototype、__proto__ 以及原型链
原文: 1.深入理解javascript原型和闭包——prototype原型 2.三张图搞懂JavaScript的原型对象与原型链 打开浏览器控制台,任意定义一个对象,打印出来后,会发现有最后一定有一 ...
- js 中的原型prototype
每次创建新函数,就会根据规则为该函数创建一个 prototype 属性,该属性是一个指向函数原型对象的指针.并且原型对象都默认拥有一个 constructor 属性,该属性是一个指向那个新建函数的指针 ...
- js中的原型、继承的一些想法
最近看到一个别人写的js类库,突然对js中的原型及继承产生了一些想法,之前也看过其中的一些内容,但是总不是很清晰,这几天利用空闲时间,对这块理解了一下,感觉还是有不通之处,思路上没那么条理,仅作为分享 ...
- 谈谈JS中的原型
不知道大家对JS中的原型理解的怎么样,我想如果大家对JS中的原型对象以及prototype属性十分熟悉的话对后面原型链以及继承的理解会十分的容易,这里想和大家分享自己对其的理解,请先看下面这段代码O( ...
- JavaScript中的原型prototype和__proto__的区别及原型链概念
问题 初学js的同学,总是搞不清楚js中的原型是什么东西,看着控制台打印出来的一串串__proto__,迷惑不已. 例如我定义一个Person,创建一个实例p,并打印实例. function Pers ...
- 说一说js中__proto__和prototype以及原型继承的那些事
在面试中遇到过,问js如何实现继承,其实最好的方式就是构造函数+原型,今天在讨论中,发现自己以前理解上的一些误区,特地写出来,最近都比较忙,等手上的项目做完,可以来做个总结. 先说我以前没有认识到位的 ...
- js中__proto__, property, prototype, 对象自身属性方法和原型中的属性方法的区别
__proto__: 这个属性是实例对象的属性,每个实例对象都有一个__proto__属性,这个属性指向实例化该实例的构造函数的原型对象(prototype). proterty:这个方法是对象的属性 ...
- js中__proto__和prototype的区别和关系?
_proto__(隐式原型)与prototype(显式原型)1.是什么 显式原型 explicit prototype property: 每一个函数在创建之后都会拥有一个名为prototype的属性 ...
随机推荐
- Coursera, Deep Learning 1, Neural Networks and Deep Learning - week3, Neural Networks Basics
NN representation 这一课主要是讲3层神经网络 下面是常见的 activation 函数.sigmoid, tanh, ReLU, leaky ReLU. Sigmoid 只用在输出0 ...
- Git命令用于检查特定提交的差异
假设你的提交日志如下(可以通过 git log 命名查看) commit 14af3315a2b1234daac74ece61ef913007043e06 Author: wuxianqiang &l ...
- python---issubclass/type/isinstance/ 反射(内置函数getattr/delattr...)
# 一 python面向对象-内置函数(issubclass(), type(), isinstance()) # issubclass 判断xxxx类是否是xxxx类的子类 class egg: p ...
- JSP动态页面技术
1.JSP和html的区别 处理过程的区别 HTML 浏览器发送一个请求到服务器,服务器找到这个页面直接返回. JSP 浏览器发送一个请求道服务器,服务器判断到时.jsp结尾,去调用JSP引擎,JSP ...
- javascript判断节点是否在dom
在项目中碰到同事写的一段代码: //焦点必须在实时dom树中 if (ele && typeof this.document.contains === "function&q ...
- mkyaffs2image 生成不了120M的镜像文件的解决方法
下载链接: http://download.csdn.net/download/macrocrazier/3807761 用上述下载的链接会出现Failed to execute /linuxrc ...
- 常用的Markdown语法
1.表格 | 左对齐标题 | 右对齐标题 | 居中对齐标题 | | :------| ------: | :------: | | 短文本 | 中等文本 | 稍微长一点的文本 | | 稍微长一点的文本 ...
- scrapy基本使用(一)
scrapy基本使用(一) 参考文档:Scrapy入门教程 http://scrapy-chs.readthedocs.io/zh_CN/0.24/intro/tutorial.html scrapy ...
- 打印手机当前界面(位于栈顶)的activity
adb shell dumpsys activity activities | grep "Hist #0" 一般第一条就是当前页(位于栈顶)的activity
- Linux 如何通过命令查看一个文件的某几行(中间几行或最后几行)
linux 如何显示一个文件的某几行(中间几行) [一]从第3000行开始,显示1000行.即显示3000~3999行 cat filename | tail -n +3000 | head -n 1 ...