JS中原型链的理解
new操作符具体干了什么呢?其实很简单,就干了三件事情。
var obj = {};
obj.__proto__ = Base.prototype;
Base.call(obj);
第一行,我们创建了一个空对象obj
第二行,我们将这个空对象的__proto__成员指向了Base函数对象prototype成员对象
第三行,我们将Base函数对象的this指针替换成obj,然后再调用Base函数,于是我们就给obj对象赋值了一个id成员变量,这个成员变量的值是”base”,关于call函数的用法。
在谈原型链之前,我们首先要了解自定义函数与 Function 之间是什么关系,而构造函数、原型和实例之间又存在什么千丝万缕的关系呢?其实,所有的函数都是 Function 的实例。在构造函数上都有一个原型属性 prototype,该属性也是一个对象;那么在原型对象上有一个 constructor 属性,该属性指向的就是构造函数;而实例对象上有一个 _proto_ 属性,该属性也指向原型对象,并且该属性不是标准属性,不可以用在编程中,该属性用于浏览器内部使用。
1 // _proto_
2 在函数里有一个属性prototype
3 由该函数创建的对象默认会连接到该属性上
4 //prototype 与 _proto_ 的关系
5 _proto_是站在对象角度来说的
6 prototype 是站在构造函数角度来说的
下面,我们来看图说话。


了解这些之后,我们再来讨论什么是原型链。说白了,其实就是有限的实例对象和原型之间组成有限链,就是用来实现共享属性和继承的。下面,我们看代码说话。

1 var obj = new Object();
2 对象是有原型对象的
3 原型对象也有原型对象
4 obj._proto_._proto_._proto_
5 原型对象也有原型对象,对象的原型对象一直往上找,会找到一个null
6 // 原型链示例
7 var arr = [];
8 arr -> Array.prototype ->Object.prototype -> null
9 var o = new Object();
10 o -> Object.prototype -> null;


function Foo1(){
this.name1 = '1';
}
function Foo2(){
this.name2 = '2';
}
Foo2.prototype = new Foo1();
function Foo3(){
this.name = '3';
}
Foo3.prototype = new Foo2();
var foo3 = new Foo3();
console.dir(foo3);



接下来就是继承问题了。
2、继承
1)原型继承

1 function Animal(name){
2 this.name = name;
3 }
4 function Tiger(color){
5 this.color = color;
6 }
7 // var tiger = new Tiger('yellow');
8 // console.log(tiger.color);
9 // console.log(tiger.name); //undefined
10 // Tiger.prototype = new Animal('老虎'); //一种方式
11 Object.prototype.name = '大老虎'; //第二种方式
12 var tiger = new Tiger('yellow');
13 console.log(tiger.color);
14 console.log(tiger.name);

2)ES5 提供了Object.create() 方法来实现继承

1 ————做兼容
2 //shim垫片
3 function create(obj){
4 if(Object.create){
5 return Object.create(obj);
6 }else{
7 function Foo(){}
8 Foo.prototype = obj;
9 return new Foo();
10 }
11 }

这种方法是ES5的新特性,其实就是复制继承。
1 var obj = {};
2 obj.extend = function(obj){
3 for(var k in obj){
4 this[k] = obj[k];
5 }
6 }

1 function Animal(name){
2 this.name = name;
3 }
4 function Mouse(nickname){
5 Animal.call(this,'老鼠');
6 this.nickname = nickname;
7 }
8 var m = new Mouse('杰瑞');
9 console.log(m.name);
10 console.log(m.nickname);

存在的问题:可以解决原型继承当中传参问题,但是父类型当中的原型对象上的成员(属性和方法)不能被继承到

1 function Person(name){
2 this.name = name;
3 }
4 Person.prototype.showName = function(){
5 console.log(this.name);
6 }
7 function Student(name,age){
8 Person.call(this,name);
9 this.age = age;
10 }
11 Student.prototype = new Person();
12 Student.prototype.contructor = Student;
13 Student.prototype.showAge = function(){
14 console.log(this.age);
15 }
16 var stu = new Student('张三',12);
17 stu.showName();
18 stu.showAge();

【原型继承+借用构造函数继承】它的特点就是属性每个实例一份,方法共享
【小结】套用一句很粗暴的话,所谓原型链就是找妈的一种行为方式,就可以理解为人是人他妈生的,妖是妖他妈生的。原型链的核心其实就只有一个:属性共享和独立的控制,当你的对象实例需要独立的属性,所有做法的本质都是在对象实例里面创建属性。若不考虑太多,你大可以在Person里面直接定义你所需要独立的属性来覆盖掉原型的属性。总之,使用原型继承的时候,要对于原型中的属性要特别注意,因为他们都是牵一发而动全身的存在。现在最常用的方法是组合模式。
1、原型链
1)构造函数、原型和实例的关系
①prototype是构造函数的属性
②_proto_是实例对象的属性
——这两者都指向同一个对象
【总结】i)函数也是对象,对象不一定是函数;
ii)对象的本质:无序的键值对集合;键值对当中的值可以是任意数据类型的值
iii)对象就是一个容器,这个容器当中放的是(属性和方法)
3)属性搜索
①在访问对象的某个成员的时候会先在对象中找是否存在
②如果当前对象中没有就在构造函数的原型对象中找
③如果原型对象中没有找到就到原型对象的原型上找
④知道Object的原型对象的原型是null为止
2、Function
——所有函数都是Function的实例
①本地对象:独立于宿主环境(浏览器)的对象——包括Object、Array、Date、RegExp、Function、Error、Number、String、Boolean
②内置对象——包括Math、Global(window,在js中就是全局变量),使用的时候不需要new
③宿主对象——包括自定义对象、DOM、BOM
JS中原型链的理解的更多相关文章
- 关于js中原型链的理解
我们创建的每个函数都有一个prototype(原型)属性,这个属性是一个指针,一个对象.无论什么时候,我们只要创建一个新函数,就会根据一组特定的规则为该函数创建一个prototype属性,这个属性对象 ...
- 前端基本知识(二):JS的原型链的理解
之前一直对于前端的基本知识不是了解很详细,基本功不扎实,但是前端开发中的基本知识才是以后职业发展的根基,虽然自己总是以一种实践是检验真理的唯一标准,写代码实践项目才是唯一,但是经常遇到知道怎么去解决这 ...
- 关于JS中原型链中的prototype与_proto_的个人理解与详细总结
一直认为原型链太过复杂,尤其看过某图后被绕晕了一整子,今天清理硬盘空间(渣电脑),偶然又看到这图,勾起了点回忆,于是索性复习一下原型链相关的内容,表达能力欠缺逻辑混乱别见怪(为了防止新人__(此处指我 ...
- JS中原型链中的prototype与_proto_的个人理解与详细总结(**************************************************************)
一直认为原型链太过复杂,尤其看过某图后被绕晕了一整子,今天清理硬盘空间(渣电脑),偶然又看到这图,勾起了点回忆,于是索性复习一下原型链相关的内容,表达能力欠缺逻辑混乱别见怪(为了防止新人__(此处指我 ...
- JS中原型链中的prototype与_proto_的个人理解与详细总结
1.对象的内部属性[[prototype]]和属性__proto__:每个对象都具有一个名为__proto__的属性: 2.函数的属性prototype:每个构造函数(构造函数标准为大写开头,如Fun ...
- JS中原型链继承
当我们通过构造函数A来实现一项功能的时候,而构造函数B中需要用到构造函数A中的属性或者方法,如果我们对B中的属性或者方法进行重写就会出现冗杂的代码,同时写出来也很是麻烦.而在js中每个函数都有个原型, ...
- 自己对js对原型链的理解
js对象分为2种 函数对象和普通对象 函数对象 比如 function Show(){}var x=function Show2(){}var b=new Function("show3&q ...
- js javascript 原型链详解
看了许多大神的博文,才少许明白了js 中原型链的概念,下面给大家浅谈一下,顺便也是为了巩固自己 首先看原型链之前先来了解一下new关键字的作用,在许多高级语言中,new是必不可少的关键字,其作用是为了 ...
- 谈谈我对 js原型链的理解
想要学习 “原型链” 必须要认识什么是 “原型” 和 “原型链” 先理解一下普通的继承和原型的区别,下面写一段js代码来帮助理解: var Animal = function(){ // 动物抽象类 ...
随机推荐
- MySql(一):linux 安装mysql数据库——yum安装法
mysql数据库有多种安装方式,本文只介绍在Linux服务器上最实用.最快捷的mysql server安装方法.一.Linux服务器yum安装(CentOS6.3 64位)所有在服务器上执行的命令,都 ...
- FPGA开发要懂得使用硬件分析仪调试——ILA
0. ILA概述在FPGA开发中,当我们写完代码,进行仿真,确定设计没有问题后,下载到硬件上一般都能按照我们的设计意愿执行相应功能.但这也并非绝对的,有时候你会遇到一些突然情况,比如时序问题或者仿真时 ...
- 基于Away3D实现全景的相机控制器。
最近研究打算做个全景的Demo,发现Away3D本身的天空盒跟全景属于两种完全不同东西.最后只能基于HoverController来扩展(原因是HoverController能提供的距离控制,类似拉近 ...
- C++语言基础(13)-抽象类和纯虚函数
一.基本语法 在C++中,可以将虚函数声明为纯虚函数,语法格式为: ; 纯虚函数没有函数体,只有函数声明,在虚函数声明的结尾加上=0,表明此函数为纯虚函数. 最后的=0并不表示函数返回值为0,它只起形 ...
- JBoss高危漏洞分析
前言 JBoss是一个基于J2EE的开放源代码应用服务器,代码遵循LGPL许可,可以在任何商业应用中免费使用:JBoss也是一个管理EJB的容器和服务器,支持EJB 1.1.EJB 2.0和EJB3规 ...
- linux前后台任务切换管理
liuyuan@ebuinfo:/var/www/projects/PHPExcel/Examples$ vi 33chartcreate-line.php & [] liuyuan@ebui ...
- 中移苏研DCOS实践之路完整篇
一.实践背景 1.1现网生产系统存在的问题 在中国移动内部各省市公司,由于技术迭代.设备更新的原因,设备繁杂,有x86server .VMware虚拟机.OpenStack虚拟机以及不同厂商的物理机( ...
- Hook length formula 学习笔记 UVALive 6625
最近做到一个关于杨氏矩阵的题目. UVALive 6625 题目大意是用n以内的数填充杨氏矩阵,要求行严格递增,列不严格递增. 求方案数. 数据范围很小,我直接上爆搜,结果TLE了. 后来发现一位学长 ...
- linux oracle sqlplus中文乱码解决
在oracle用户的~/.bash_profile中添加 NLS_LANG="SIMPLIFIED CHINESE"_CHINA.ZHS16GBKexport NLS_LANG 然 ...
- 微信 oauth授权2
2.前面请求成功后 会在跳转url后得到 ?code=00b788e3b42043c8459a57a8d8ab5d9f&state=1 3.之后 使用code换取access_token 换取 ...