【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, Machine Learning, Unsupervised Learning,  K-means, Dimentionality Reduction
			
Clustering K-means: 基本思想是先随机选择要分类数目的点,然后找出距离这些点最近的training data 着色,距离哪个点近就算哪种类型,再对每种分类算出平均值,把中心点移动到 ...
 - tab选项卡在鼠标经过时实现切换延迟
			
偶然间在浏览网页时,发现这样的效果.当鼠标不经意间滑过tab时并不会切换,当鼠标停留在上面一段时候后才会切换. 个人觉得用户体验不错,优点是1.当用户只是滑过标签,并不需要切换,而此时如果切换标签需要 ...
 - python前后端加密方式
			
后端加密方法: python后端加密方式: # 双重工加密 #bytes((7788).encode('utf-8')):为后端加密二把手,多加的锁,该参数可为空,必须加bytes才能实现 md5pa ...
 - 4-20模块 序列化模块 hashlib模块
			
1,模块,py文件就是模块,py之所以好用就是模块多. 2,模块的分类: 1,内置模块,python 安装时自带的模块 2,扩展模块,别人写好的,需要安装之后,可以直接使用.itchat微信模块, b ...
 - 将本地项目上传到git
			
1.新建一个README.md的文件,并将项目名写入此文件(一般第三方git服务会在创建在创建项目的时候自动创建该文件,可以跳过这一步) echo "# Lee" >> ...
 - tfs二次开发-利用tfs api做查询
			
参考地址:https://msdn.microsoft.com/en-us/library/bb130306(v=vs.120).aspx You can query for bugs, tasks, ...
 - 模拟post表单提交参数
			
Content-Type: application/x-www-form-urlencoded;charset=utf-8
 - Java 遍历List中删除的解决方法
 - 方法join()使用详解
			
在线程的常见方法一节中,已经接触过join()方法的使用. 在很多情况下,主线程创建并启动子线程,如果子线程中要进行大量的耗时运算,主线程将早于子线程结束.这时,如果主线程想等子线程执行完成才结束,比 ...
 - gitlab的配置
			
一. 管理员配置 gitlab 1. 登录 gitlab 等待 docker 容器启动完成后, 登陆 http://localhost:8080 第一次访问是让我们修改管理员密码.如下所示 初始化 g ...