最近面试被问到了就决定好好深入理解原型链

对象

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

  • 普通对象
    • 最普通的对象:有__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。

 

JS原型链详解的更多相关文章

  1. js 原型链详解

    目录 构造函数和实例 属性Prototype 属性__proto__ 访问原型上的方法 构造函数也有__proto__ 构造函数的原型也有__proto__ Object.prototype这个原型对 ...

  2. JS原型链详解(2)

    深入理解javascript原型链 在javascript中原型和原型链是一个很神奇的东西,对于大多数人也是最难理解的一部分,掌握原型和原型链的本质是javascript进阶的重要一环.今天我分享一下 ...

  3. 你不知道的JavaScript--Item15 prototype原型和原型链详解

    用过JavaScript的同学们肯定都对prototype如雷贯耳,但是这究竟是个什么东西却让初学者莫衷一是,只知道函数都会有一个prototype属性,可以为其添加函数供实例访问,其它的就不清楚了, ...

  4. 《前端之路》之 JavaScript原型及原型链详解

    05:JS 原型链 在 JavaScript 的世界中,万物皆对象! 但是这各种各样的对象其实具体来划分的话就 2 种. 一种是 函数对象,剩下的就是 普通对象.其中 Function 和 Objec ...

  5. js javascript 原型链详解

    看了许多大神的博文,才少许明白了js 中原型链的概念,下面给大家浅谈一下,顺便也是为了巩固自己 首先看原型链之前先来了解一下new关键字的作用,在许多高级语言中,new是必不可少的关键字,其作用是为了 ...

  6. JavaScript学习总结(五)原型和原型链详解

    转自:http://segmentfault.com/a/1190000000662547 私有变量和函数 在函数内部定义的变量和函数,如果不对外提供接口,外部是无法访问到的,也就是该函数的私有的变量 ...

  7. JavaScript prototype原型和原型链详解

    用过JavaScript的同学们肯定都对prototype如雷贯耳,但是这究竟是个什么东西却让初学者莫衷一是,只知道函数都会有一个prototype属性,可以为其添加函数供实例访问,其它的就不清楚了, ...

  8. JavaScript的面向对象原理之原型链详解

    一.引言 在16年的10月份,在校内双选会找前端实习的时候,hr问了一个问题:JavaScript的面向对象理解吗?我张口就说“JavaScript是基于原型的!”.然后就没什么好说的了,hr可能不知 ...

  9. javascript 原型及原型链详解

    我们创建的每个函数都有一个 prototype (原型)属性,这个属性是一个指针,指向一个原型对象,而这个原型对象中拥有的属性和方法可以被所以实例共享. function Person(){ } Pe ...

随机推荐

  1. h5与app交互

    现在移动端 web 应用,很多时候都需要与原生 app 进行交互.沟通(运行在 webview中),比如微信的 jssdk,通过 window.wx 对象调用一些原生 app 的功能.所以,这次就来捋 ...

  2. 基于socket实现大文件上传

    import socket 1.客户端: 操作流程: 先拿到文件--->获取文件大小---->创建字典 1.制作表头 header  如何得到 他是一个二进制字符串 序列化得到 字典字符串 ...

  3. win7安装scrapy

    Scrapy Scrapy是一个为了爬取网站数据,提取结构性数据而编写的应用框架. 其可以应用在数据挖掘,信息处理或存储历史数据等一系列的程序中.其最初是为了页面抓取 (更确切来说, 网络抓取 )所设 ...

  4. SIGINT、SIGQUIT、 SIGTERM、SIGSTOP区别

    2) SIGINT程序终止(interrupt)信号, 在用户键入INTR字符(通常是Ctrl-C)时发出,用于通知前台进程组终止进程. 3) SIGQUIT和SIGINT类似, 但由QUIT字符(通 ...

  5. Linux性能优化从入门到实战:17 网络篇:网络基础

    网络模型 为了解决网络互联中异构设备的兼容性问题,并解耦复杂的网络包处理流程,国际标准化组织制定了开放式系统互联通信参考模型(Open System Interconnection Reference ...

  6. uboot移植之迷雾解码

    按照蜗窝科技的步骤执行 一.有关硬件描述的填空题 1)CPU上电后,从哪种设备(       BOOTROM         )的哪个地址(        0x0000_0000       )开始执 ...

  7. Ts 的类

    TS 中的公共.私有和受保护的修饰符: 1.public表示公共的,用来指定在创建实例后可以通过实例访问的,也就是类定义的外部可以访问的属性和方法.默认是 public 2.private修饰符表示私 ...

  8. thinkphp 模板

    一. 模板函数  教程https://www.kancloud.cn/manual/thinkphp5/125005 我们往往需要对模板输出变量使用函数,可以使用: {$data.name|md5} ...

  9. python语句执行

    python文件中的语句,按顺序执行,执行import时,原文件会入栈,等import文件执行完成后,才会出栈执行. load/const.py --- import os DB_ADDRESS = ...

  10. Django中ifequal 和ifnotequal的使用

    Django中{% ifequal A B %} 用来比较A和B两个值是否相等,{% ifnotequal A B %}` 用来比较A和B两个值是否不相等..如: {% ifequal user cu ...