想要学习 “原型链” 必须要认识什么是 “原型” 和 “原型链”

先理解一下普通的继承和原型的区别,下面写一段js代码来帮助理解:

var Animal = function(){ // 动物抽象类

  this.name;
  this.age;
  this.sex;   this.skill = function(){};
  this.die = function(){};
}; var Dog = function(){};
var Cat = function(){}; Dog = new Animal(); // 这里Dog就是具体的动物对象 它拥有动物的公有属性 【 name, age, sex, func:sikll, func:die 】
Cat = new Animal(); // 这里Cat也是具体的动物对象 它呢也拥有动物的公有属性【 name, age, sex, func:sikll, func:die 】

Dog 和 Cat 同时继承了 Animal 也就是说他们都拥有 【 name, age, sex, func:sikll, func:die 】这些属性。 那么他们和原型的区别是什么呢?

区别就是:不管是 Dog继承或是Cat继承又或者是其它具体类继承了Animal ,各自都会复制一份 Animal内部的结构(大脑里构建一下这样的场景), 试想一下,如果有几十个上百个具体类继承了Animal 难道还要复制几十个上百个Animal内部结构吗?

那怎么解决上面多复制的问题呢? 那这就是“原型”要解决的问题咯, 对的就是说使用原型后不管有多少个类继承Animal 它内部的结构只复制一次。 够明白了吗? 这就是原型的概念!

我们把上面的代码改动一下,看看原型的写法:

var Animal = function(){ // 动物抽象类

  this.name;
  this.age;
  this.sex; }; Animal.prototype.skill = function(){};
Animal.prototype.die = function(){}; var Dog = function(){};
var Cat = function(){}; Dog.prototype = new Animal();
Cat.prototype = new Animal();

这样写就可以继承Animal类下的所有字段和方法,但是这里有个小问题,就是说 skill 和 die 可以正常调用,因为他们是函数 。 但是name / age / sex 这三个字段只能读,如果你写 Dog.name = "旺财";  这样系统会认为name是 Dog下的name 而不是 Animal下的name (这句话如果看不懂等会看原型链就会懂的)。

为什么要说一下这个小问题呢, 因为有很多人认为他们是共享的只要修改了 dog 那么 cat 的name 也会改变, 这里纠正一下哈,以后不要这么认为了。

那么如果只想继承Animal类的原型 而不继承字段应该怎么办呢, 那我们在来改动一下代码:

var Animal = function(){ // 动物抽象类

  this.name;
  this.age;
  this.sex; }; Animal.prototype.skill = function(){};
Animal.prototype.die = function(){}; var Dog = function(){};
var Cat = function(){}; Dog.prototype = Animal.prototype;
Cat.prototype = Animal.prototype;

是的 Dog.prototype = Animal.prototype; 这样写就可以了,这样就可以有效的屏蔽Animal类的字段了,可以放心的使用它的原型函数了。

那原型链又是一个什么概念呢?其实js的原型链也很好理解我们先来看一个案例

var Animal = function(){ // 动物抽象类

  this.name = "二哈";
  this.age = "1";
  this.sex = "公狗"; }; Animal.prototype.skill = function(){};
Animal.prototype.die = function(){}; var Dog = function(){}; Dog.prototype = new Animal(); Dog.name = "旺财";
Dog.shout = "汪汪汪"; console.log(Dog.name); // 输出的是 旺财 而不是 二哈
console.log(Dog.shout); // 输出的是 汪汪汪 console.log(Dog.sex); // 输出的是公狗
 

根据这个案例怎么来理解原型链呢? 我们先来看 Dog.name 为什么会输出旺财 而不是二哈呢? 因为js解析时会先找 dog下面是否有name , 如果dog下面没有name就会去 dog的prototype原型里找 name 如果dog.prototype原型里也没有name 就会去object里去找,

如果还找不到那就是没有定义, 那么dog下面有个name 那么 animal下面也有个name js解析的时候会先找到最近的 dog下的name, 所以输出的是 旺财 而不是 二哈

理所当然 Dog.shout 输出的也是 dog下的 shout , 但是 dog 下面没有找到 sex 属性,所以就去  dog.prototype下找到 sex 字段并输出;

理解原型链查找路线图  dog->animal->object  简而言之就是 先找dog下的字段, 再找 animal下的字段, 最后是 object下的字段  这就是原型链的运行轨迹!!!

谈谈我对 js原型链的理解的更多相关文章

  1. JS原型链的理解和使用(一)

    一些个人的理解,不一定是对的,仅供参考. 在JS中有函数和对象两个概念,而又有一切皆对象的概念及函数也是一个对象.所以可以说函数一定可以作为一个对象,而对象不一定是一个函数. 也可以说在js中对象分为 ...

  2. js原型链结构理解

    在一般的面向对象的语言中,都存在类(class)的概念,类就是对象的模板,对象就是类的实例. 但在js中是没有类的定义的(万物皆是对象).  题外话:但是在ES6中提供了更接近传统语言的写法,引入了C ...

  3. JS原型链的理解和使用(二)

    根据在创建对象的时候,创建出来的对象的__proto__指向创建这个对象的函数的prototype属性. 由于在调用对象的属性或者方法的时候会首先在对象的作用域中查找指定的属性或者方法,如果未找到则会 ...

  4. 分享一个关于js原型链的理解

    http://www.cnblogs.com/wyaocn/p/5815761.html

  5. 深入理解JS原型链与继承

    我 觉得阅读精彩的文章是提升自己最快的方法,而且我发现人在不同阶段看待同样的东西都会有不同的收获,有一天你看到一本好书或者好的文章,请记得收藏起来, 隔断时间再去看看,我想应该会有很大的收获.其实今天 ...

  6. 简单粗暴地理解js原型链–js面向对象编程

    简单粗暴地理解js原型链–js面向对象编程 作者:茄果 链接:http://www.cnblogs.com/qieguo/archive/2016/05/03/5451626.html 原型链理解起来 ...

  7. js原型链理解(2)--原型链继承

    1.原型链继承 2.constructor stealing(构造借用) 3.组合继承 js中的原型链继承,运用的js原型链中的__proto__. function Super(){ this.se ...

  8. 深入分析JS原型链以及为什么不能在原型链上使用对象

    在刚刚接触JS原型链的时候都会接触到一个熟悉的名词:prototype:如果你曾经深入过prototype,你会接触到另一个名词:__proto__(注意:两边各有两条下划线,不是一条).以下将会围绕 ...

  9. JS 原型链图形详解

    JS原型链 这篇文章是「深入ECMA-262-3」系列的一个概览和摘要.每个部分都包含了对应章节的链接,所以你可以阅读它们以便对其有更深的理解. 对象 ECMAScript做为一个高度抽象的面向对象语 ...

随机推荐

  1. python之99乘法表

    #99乘法表 fir=1 while fir<=9: sec=1 while sec<=fir: print(str(fir)+'*'+str(sec)+'='+str(fir*sec)) ...

  2. 手机端flex、字体设置、快速点击

    ;(function flexible (window, document) { var docEl = document.documentElement ♥1 var dpr = window.de ...

  3. TCP长连接与短连接、心跳机制

    1. TCP连接 当网络通信时采用TCP协议时,在真正的读写操作之前,server与client之间必须建立一个连接,当读写操作完成后,双方不再需要这个连接时它们可以释放这个连接,连接的建立是需要三次 ...

  4. Java学习笔记(9)

    lambda表达式: 只定义了单个方法的接口,称为单一抽象方法(Single Abstract Method, SAM)接口:由于此接口通过调用,完成某一功能,所以也称为功能接口,此类接口的实例称为功 ...

  5. ELFHash算法解释

    // ELF Hash Function unsigned int ELFHash(char *str) { unsigned int hash = 0; unsigned int x = 0; wh ...

  6. Laravel Scout 开启队列, 自定义queue name和queue connection

    scout.php的默认配置: 'queue' => env('SCOUT_QUEUE', false), 修改为: 'queue' => [ 'queue' => env('SCO ...

  7. vue项目中全局配置变量

    在项目中api管理需要用到全局变量,创建全局变量的方式也有很多. 1.通过export default const BASEURL = "http://localhost:3333/&quo ...

  8. aiohttp AppRunner的用法

    参考廖雪峰的aiohttp教程,会出现两个DeprecationWarning, loop argument is deprecated Application.make_handler(...) i ...

  9. c++中的两种getline用法

    参考 https://blog.csdn.net/Big_laoshu/article/details/79345351

  10. 固态硬盘Ghost安装Windows 10无法引导的问题

    机器配置如下: 电脑型号 技嘉 B360M POWER 台式电脑 操作系统 Windows 10 64位 ( DirectX 12 ) 处理器 英特尔 Core i7-8700 @ 3.20GHz 六 ...