Javascript中prototype与__proto__的关系详解


Posted in Javascript onMarch 11, 2018

前言

学到原型的时候感觉头都大了/(ㄒoㄒ)/~~ 尤其是prototype和__proto__ 傻傻分不清  通过多番查找资料,根据自己的理解,总结如下:

一、构造函数:

构造函数:通过new关键字可以用来创建特定类型的对象的函数。比如像Object和Array,两者属于内置的原生的构造函数,在运行时会自动的出现在执行环境中,可以直接使用。如下:

var arr = new Array();//使用Array构造函数创建了一个array实例arr
arr[0]="a";
arr[1]="b";
alert(arr);//a,b

var obj=new Object();//使用Object构造函数创建了一个Object实例obj
obj.name="c";
obj.age=12;
alert(obj.name);//c

我们可以自定义的创建构造函数,并为其自定义属性和方法,如:

//创建构造函数Person
function Person(name,age){
 this.name=name;
 this.age=age;
 this.sayName=function(){
 alert(this.name)//
 };
}

//使用new关键字,来生成Person实例
var person1=new Person("Tom",22);
var person2=new Person("Jerry",21);
person1.sayName();//Tom
person2.sayName();//Jerry

注意以下几点:

  • 构造函数的名字始终要以大写字母开头(主要是为了区别于非构造函数,也即是区别于普通函数)
  • 构造函数也就是函数,定义构造函数和定义普通函数的语法一样。构造函数和普通函数的区别在于:使用他们的方式不同。任何函数只要使用new操作符来调用,那他就可以作为构造函数;不使用new操作符来调用就是普通函数
function Person(name,age){
 this.name=name;
 this.age=age;
 this.sayName=function(){
 alert(this.name)//
 };
}

//当做构造函数使用
var person=new Person("Tom",22);
person.sayName();//Tom 
//当做普通函数使用
Person("Jerry",30);//添加到window
sayName();//Jerry 等同于window.sayName();

二、原型对象:

每个函数都有一个prototype属性,它是一个指向原型对象的指针,原型对象在定义函数时同时被创建,原型对象的用途是包含所有实例共享的属性和方法

function Person(){
}
//自定义原型对象的属性和方法
Person.prototype.name="Tom";
Person.prototype.age=25;
Person.prototype.sayName=function(){
 alert(this.name);
};
//原型对象中的所有属性和方法 都会自动被所有实例所共享
var person1=new Person();
var person2=new Person();
person1.sayName();//Tom
person2.sayName();//Tom

只要创建了一个新函数,每个函数在创建之后都会获得一个prototype的属性,这个属性指向函数的原型对象(原型对象在定义函数时同时被创建),此原型对象又有一个名为“constructor”的属性,反过来指向函数本身,达到一种循环指向,

如在上边的例子中:alert(Person.prototype.constructor===Person);//会返回true

function Person(){}
alert(Person.prototype.constructor===Person);//true

三、__proto__(注意这里proto左右两边都有两个"_")

当调用构造函数创建一个新实例后,该实例的内部将包含一个指针[[Prototype]],该指针指向创建它的构造函数的原型,在脚本上没有标准的方法来访问[[Prototype]],但大多数浏览器都支持通过__proto__来访问。

function Person(){
}
//自定义原型对象的属性和方法
Person.prototype.name="Tom";
Person.prototype.age=25;
Person.prototype.sayName=function(){
 alert(this.name);
};
//原型对象中的所有属性和方法 都会自动被所有实例所共享
var person1=new Person();
var person2=new Person();
person1.sayName();//Tom
person2.sayName();//Tom
alert(person1.__proto__===Person.prototype);//true

以上述的示例代码为例,各个对象之间的关系如下图所示:

 Javascript中prototype与__proto__的关系详解

总结:

①只要创建了一个函数,该函数的原型对象也随之同时被创建出来,原型对象中的属性和方法被经由其相对应的构造函数所创建的实例所共享

②每个函数在创建之后都会获得一个prototype的属性,这个属性指向该函数的原型对象

③每个对象的__proto__属性都指向其构造函数的原型

好了,以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对三水点靠木的支持。

Javascript 相关文章推荐
javascript 面向对象编程基础 多态
Aug 21 Javascript
统计jQuery中各字符串出现次数的工具
May 03 Javascript
js快速排序的实现代码
Dec 08 Javascript
javascript判断是否按回车键并解决浏览器之间的差异
May 13 Javascript
JavaScript获取当前cpu使用率的方法
Dec 15 Javascript
JavaScript阻止回车提交表单的方法
Dec 30 Javascript
jQuery插件HighCharts绘制简单2D柱状图效果示例【附demo源码】
Mar 21 jQuery
js实现点击切换checkbox背景图片的简单实例
May 08 Javascript
实例分析JS与Node.js中的事件循环
Dec 12 Javascript
Angular异步变同步处理方法
Aug 13 Javascript
node中短信api实现验证码登录的示例代码
Jan 20 Javascript
使用原生javascript开发计算器实例代码
Feb 21 Javascript
js中document.write和document.writeln的区别
Mar 11 #Javascript
Javascript 编码约定(编码规范)
Mar 11 #Javascript
JavaScript获取移动设备型号的实现代码(JS获取手机型号和系统)
Mar 10 #Javascript
js经验分享 JavaScript反调试技巧
Mar 10 #Javascript
webpack打包node.js后端项目的方法
Mar 10 #Javascript
webpack external模块的具体使用
Mar 10 #Javascript
webpack组织模块打包Library的原理及实现
Mar 10 #Javascript
You might like
博士208HAF收音机实习报告
2021/03/02 无线电
PHP开发中常用的三个表单验证函数使用小结
2010/03/03 PHP
自编函数解决pathinfo()函数处理中文问题
2014/11/03 PHP
Zend Framework动作助手Redirector用法实例详解
2016/03/05 PHP
PHP递归实现层级树状展开
2016/04/01 PHP
JavaScript中数组的排序、乱序和搜索实现代码
2011/11/30 Javascript
js对象关系图 方便dom操作
2012/03/18 Javascript
node.js入门教程迷你书、node.js入门web应用开发完全示例
2014/04/06 Javascript
jQuery操作元素css样式的三种方法
2014/06/04 Javascript
window.location的重写及判断location是否被重写
2014/09/04 Javascript
javascript 原型链维护和继承详解
2014/11/26 Javascript
javascript中undefined与null的区别
2015/08/16 Javascript
jquery 重写 ajax提交并判断权限后 使用load方法报错解决方法
2016/01/19 Javascript
微信小程序五星评分效果实现代码
2017/04/06 Javascript
AngularJS中table表格基本操作示例
2017/10/10 Javascript
JS声明对象时属性名加引号与不加引号的问题及解决方法
2018/02/16 Javascript
vue.js 实现图片本地预览 裁剪 压缩 上传功能
2018/03/01 Javascript
JS添加或删除HTML dom元素的方法实例分析
2019/03/05 Javascript
Vue v-for循环之@click点击事件获取元素示例
2019/11/09 Javascript
JQuery中的常用事件、对象属性与使用方法分析
2019/12/23 jQuery
PyCharm搭建Spark开发环境实现第一个pyspark程序
2019/06/13 Python
python 使用opencv 把视频分割成图片示例
2019/12/12 Python
利用Python脚本实现自动刷网课
2020/02/03 Python
使用Canvas操作像素的方法
2018/06/14 HTML / CSS
什么时候需要进行强制类型转换
2016/09/03 面试题
《永远的白衣战士》教学反思
2014/04/25 职场文书
仓库管理计划书
2014/05/04 职场文书
活动宣传策划方案
2014/05/23 职场文书
小学生2014国庆节演讲稿:祖国在我心中
2014/09/21 职场文书
工伤事故赔偿协议书(标准)
2014/09/29 职场文书
实习工作表现评语
2014/12/31 职场文书
关爱留守儿童捐款倡议书
2015/04/27 职场文书
入伍志愿书怎么写?
2019/07/19 职场文书
PyQt5 QThread倒计时功能的实现代码
2021/04/02 Python
oracle表分区的概念及操作
2021/04/24 Oracle
MySQL 存储过程的优缺点分析
2021/05/20 MySQL