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

先理解一下普通的继承和原型的区别,下面写一段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. 最近学习的 Node.js 基础:安装、环境配置、forever

    最近工作中,因为某某某某原因,需要用到Node.js  . 发现在很多方面和python很像,比如generator / yield ,比如模块的使用方式,比如http模块. 先安装个环境,windo ...

  2. ubuntu 下redis的安装简介

    Linux公社:https://www.linuxidc.com/topicnews.aspx?page=2&tid=2 简单介绍下ubuntu下redis的安装方式: 第一种: 1:进入re ...

  3. dos4章

    批处理中的变量,我把他分为两类,分别为"系统变量"和"自定义变量" 我们现在来详解这两个变量! 一.系统变量 他们的值由系统将其根据事先定义的条件自动赋值,也就 ...

  4. SpringBoot的学习【6.YML 和 Properties 的语法】

    1.YML的基本语法 KEY:(空格)value:(空格) 以空格的缩进来表示同一层级.属性和值是大小写敏感的. 2.YML和属性.属性值进行匹配 注解:@ConfigurationPropertie ...

  5. @RequestParam 和 @ PathVariable 的区别

    @RequestParam 和 @ PathVariable 的区别http://localhost:8080/Springmvc/user/page.do?pageSize=3&pageNo ...

  6. 为什么 EXISTS(NOT EXIST) 与 JOIN(LEFT JOIN) 的性能会比 IN(NOT IN) 好

    前言 网络上有大量的资料提及将 IN 改成 JOIN 或者 exist,然后修改完成之后确实变快了,可是为什么会变快呢?IN.EXIST.JOIN 在 MySQL 中的实现逻辑如何理解呢?本文也是比较 ...

  7. git配置代理

    1.查看当前代理 git config --global http.proxy 2.配置git走代理,可走http代理也可以走socks5代理,可根据自己的代理协议而定 #http代理 git con ...

  8. 记一次H5页面卡死的BUG

    之前有次开发小程序内嵌页面,类似于网易星球那种,很多钻石可以手动点击收取. 该页面css动效非常多,几乎页面上除了纯色背景之外全部有动效. 也正因为如此,才做成了小程序内嵌的形式(太大了). 当多次快 ...

  9. 12集合(2)-----Set

    一.总体分类 Collection(包括方法add,remove,contains,clear,size) List(接口) LinkedList ArrayList Vector---Stack 2 ...

  10. jQuery 追加元素、拼接元素的方法总结(append、html、insertBefore、before等)

    1. append & appendTo 的功能均为:在被选元素结尾(仍在元素内部)插入指定内容,但是内容和选择器的位置不同 (1) append()方法: $("#test&quo ...