对象

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

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

    • 凡是通过new Function()创建的都是函数对象。

拥有__proto__、prototype属性(指向原型对象)。

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

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

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

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

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

原型对象

 

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

        第一块中有提到,原型对象属于普通对象。Function.prototype是个例外,它是原型对象,却又是函数对象,作为一个函数对象,它又没有prototype属性。
  1. function person(){};
  2. console.log(typeof person.prototype) //Object
  3. console.log(typeof Object.prototype) // Object
  4. console.log(typeof Function.prototype) // 特殊 Function
  5. console.log(typeof Function.prototype.prototype) //undefined 函数对象却没有prototype属性

解释:

functionperson(){};

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

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

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

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

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

原型链

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

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

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

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

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

原型链基本思路:

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

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

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

举例说明:

  1. function animal(){
  2. this.type = "animal";
  3. }
  4. animal.prototype.getType = function(){
  5. return this.type;
  6. }
  7. function dog(){
  8. this.name = "dog";
  9. }
  10. dog.prototype = new animal();
  11. dog.prototype.getName = function(){
  12. return this.name;
  13. }
  14. var xiaohuang = new dog();
  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。

最新文章

  1. jQuery 更改checkbox的状态,无效
  2. linux tomca几个配置文件及点
  3. TEdit,TMemo背景透明
  4. Google Android开发入门与实战
  5. JavaScript实现私有属性
  6. div光标定位问题总结
  7. 立一个Flag吧
  8. CSS选择器中的特殊性
  9. java 使用 WebUploader
  10. 【Hadoop学习之八】MapReduce开发
  11. ESPCN处理彩色图像代码
  12. 209. Minimum Size Subarray Sum(双指针)
  13. 20165230 2017-2018-2 《Java程序设计》第8周学习总结
  14. [Code Festival 2017 qual A] C: Palindromic Matrix
  15. IEEEXtreme 10.0 - Game of Stones
  16. POJ_3264 Balanced Lineup 【线段树 + 区间查询】
  17. fullpage的使用以及less, Sass的属性和JQuery自定义插件的声明和使用
  18. Xcode5根控制器使用xib展示的步骤
  19. Android(java)学习笔记153:采用post请求提交数据到服务器(qq登录案例)
  20. java之接口相关知识

热门文章

  1. 莫烦theano学习自修第七天【回归结果可视化】
  2. Java HashMap的put操作(Java1.8)
  3. dom定位的三种元素
  4. kubernetes ceph-rbd挂载步骤 类型PersistentVolume
  5. django-pure-pagination 组件使用
  6. npm 淘宝源
  7. 【C++】实现一个简单的单例模式
  8. 洛谷AT2046 Namori(思维,基环树,树形DP)
  9. BZOJ4671 异或图(容斥+线性基)
  10. 自学Python之路-Python基础+模块+面向对象+函数