博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
JS原型,原型链
阅读量:5799 次
发布时间:2019-06-18

本文共 3332 字,大约阅读时间需要 11 分钟。

hot3.png

对象

要清楚原型链,首先要弄清楚对象:

 

  • 普通对象

 

 

    • 最普通的对象:有__proto__属性(指向其原型链),没有prototype属性。
    • 原型对象(person.prototype 原型对象还有constructor属性(指向构造函数对象))

 

  • 函数对象:
    • 凡是通过new Function()创建的都是函数对象。
                          拥有__proto__、prototype属性(指向原型对象)。

                          Function、Object、Array、Date、String、自定义函数

                          特例: Function.prototype(是原型对象,却是函数对象,下面会有解释)

[javascript]  

  1. 函数对象  
  2. function f1(){};  
  3. var f2 = function(){};  
  4. var f3 = function("n1","n2","return n1+n2");  
  5.   
  6. console.log(typeof f1);  //function  
  7. console.log(typeof f2);  //function  
  8. console.log(typeof f3);   //function  
  9. console.log(typeof Object);   //function  
  10. console.log(typeof Array);   //function  
  11. console.log(typeof String);   //function  
  12. console.log(typeof Date);   //function  
  13. console.log(typeof Function);   //function  

Array是函数对象,是Function的实例对象,Array是通过newFunction创建出来的。因为Array是Function的实例,所以Array.__proto__ ===  Function.prototype

 

[javascript]  

  1. 普通对象  
  2. var o1 = new f1();   
  3. var o2 = {};         
  4. var o3 = new Object();   
  5.   
  6. console.log(typeof o1);  //Object  
  7. console.log(typeof o2);   //Object  
  8. console.log(typeof o3);   //Object  

 

原型对象

 

        每创建一个函数都会有一个prototype属性,这个属性是一个指针,指向一个对象(通过该构造函数创建实例对象的原型对象)。原型对象是包含特定类型的所有实例共享的属性和方法。原型对象的好处是,可以让所有实例对象共享它所包含的属性和方法。

        第一块中有提到,原型对象属于普通对象。Function.prototype是个例外,它是原型对象,却又是函数对象,作为一个函数对象,它又没有prototype属性。

[javascript]   
  1. function person(){};  
  2.   
  3. console.log(typeof person.prototype) //Object  
  4. console.log(typeof Object.prototype) // Object  
  5. console.log(typeof Function.prototype) // 特殊 Function  
  6. console.log(typeof Function.prototype.prototype) //undefined 函数对象却没有prototype属性  

解释:

     functionperson(){};

        其实原型对象就是构造函数的一个实例对象。person.prototype就是person的一个实例对象。相当于在person创建的时候,自动创建了一个它的实例,并且把这个实例赋值给了prototype。

 

[javascript]   
  1.  function person(){};  
  2. var temp = new person();  
  3. person.prototype = temp;  
  4.   
  5. function Function(){};  
  6. var temp = new Function();  
  7. Function.prototype = temp; //由new Function()产生的对象都是函数对象  
 

 

        从一张图看懂原型对象、构造函数、实例对象之间的关系

 

[javascript]   
  1. function Dog(){};  
  2.   
  3. Dog.prototype.name = "小黄";  
  4. Dog.prototype.age =  13;  
  5. Dog.prototype.getAge = function(){  
  6.     return this.age;  
  7. }  
  8.   
  9. var dog1 = new Dog();  
  10. var dog2 = new Dog();  
  11.   
  12. dog2.name = "小黑";  
  13. console.log(dog1.name); // 小黄 来自原型  
  14. console.log(dog2.name); // 小黑 来自实例  
 

 

 

 

[javascript]   
  1. //图中的一些关系  
  2. dog1.__proto__ === Dog.prototype  
  3.   
  4. Dog.prototype.__proto__ === Object.prototype //继承Object 下面原型链说  
  5.   
  6. dog1.__proto__.__proto__ === Object.prototype  
  7.   
  8. Dog.prototype.constructor === Dog   
  9.   
  10. Dog.prototype.isPrototypeOf(dog1)  
  11.   
  12. 获取对象的原型  
  13. dog1.__proto__  //不推荐  
  14. Object.getPrototypeOf(dog1) === Dog.prototype   //推荐  
 

 

原型链

原型链是实现继承的主要方法。

 

先说一下继承,许多OO语言都支持两张继承方式:接口继承、实现继承。

|- 接口继承:只继承方法签名

|- 实现继承:继承实际的方法

由于函数没有签名,在ECMAScript中无法实现接口继承,只支持实现继承,而实现继承主要是依靠原型链来实现。

 

 

原型链基本思路:

 

利用原型让一个引用类型继承另一个引用类型的属性和方法。

 

每个构造函数都有一个原型对象,原型对象都包含一个指向构造函数想指针(constructor),而实例对象都包含一个指向原型对象的内部指针(__proto__)。如果让原型对象等于另一个类型的实例,此时的原型对象将包含一个指向另一个原型的指针(__proto__),另一个原型也包含着一个指向另一个构造函数的指针(constructor)。假如另一个原型又是另一个类型的实例……这就构成了实例与原型的链条。

 

原型链基本思路(图解):

 

 

 

举例说明:

 

[javascript]   
  1. function animal(){  
  2.     this.type = "animal";  
  3. }  
  4. animal.prototype.getType = function(){  
  5.     return this.type;  
  6. }  
  7.   
  8. function dog(){  
  9.     this.name = "dog";  
  10. }  
  11. dog.prototype = new animal();  
  12.   
  13. dog.prototype.getName = function(){  
  14.     return this.name;  
  15. }  
  16.   
  17. var xiaohuang = new dog();  

 

[javascript]   
  1. //原型链关系  
  2. xiaohuang.__proto__ === dog.prototype  
  3. dog.prototype.__proto__ === animal.prototype  
  4. animal.prototype.__proto__ === Object.prototype  
  5. Object.prototype.__proto__ === null  
 

图解:

 

详细图

从xiaohuang这个实例,看出整个链条

 

 

总结:

 

Xiaohuang这个Dog的实例对象继承了Animal,Animal继承了Object。

转载于:https://my.oschina.net/u/2332658/blog/468421

你可能感兴趣的文章
父类引用指向子类对象详解
查看>>
View 事件分发源码分析
查看>>
如何从复杂单体应用快速迁移到微服务?
查看>>
iOS多种刷新样式、音乐播放器、仿抖音视频、旅游App等源码
查看>>
线程池很容易理解的
查看>>
彻底理解数据库事务
查看>>
Oracle学习日志-1(基本概念)
查看>>
移动开发之混合编程第一步:为JavaScript定义Class-based编程风格
查看>>
Spring之事务管理
查看>>
android之数据库和Content Provider(一)
查看>>
HTML5标准常用的表单写法和使用表单2.0定制错误提示消息内容
查看>>
Hadoop - 企业级大数据管理平台CDH(安装Hadoop组件)
查看>>
OSChina 周一乱弹 ——听过煲仔饭吗?老婆饼呢?
查看>>
OSChina 周一乱弹 ——程序员已经习惯熬夜了吧
查看>>
OSChina 周五乱弹 —— 这就是不要女朋友的理由
查看>>
OSChina 周三乱弹 —— 舍得把亲人送到养老院么
查看>>
Mybatis源码学习 - ExceptionContext
查看>>
查看linux 目录大小
查看>>
安全漏洞整改 禁用 WebDAV
查看>>
js 文件的页面载入
查看>>