博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
JS——构造函数、原型与实例之间的关系 及 原型链 的描述
阅读量:5116 次
发布时间:2019-06-13

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

本文转载自:https://www.cnblogs.com/sarahwang/p/6870072.html  

      https://blog.csdn.net/u012443286/article/details/78823955    ——仅用于学习

构造函数、原型与实例之间的关系

  

  》每创建一个函数,该函数就会自动带有一个 prototype 属性。该属性是个指针,指向了一个对象,我们称之为 原型对象

  》原型对象上默认有一个属性 constructor,该属性也是一个指针,指向其相关联的构造函数。

  》通过调用构造函数产生的实例,都有一个内部属性(__proto__),指向了原型对象。所以实例能够访问原型对象上的所有属性和方法。

  

  所以三者的关系是:  "每个构造函数都有一个原型对象,

               原型对象都包含一个指向构造函数的指针,

               实例都包含一个指向原型对象的内部指针。"

                  ——此段话摘自

  -----通俗点说就是,实例通过内部指针可以访问到原型对象,原型对象通过constructor指针,又可以找到构造函数。

  =================================================================

  下面结合实例简要分析:

      一、每个构造函数都有一个原型对象 

         

          可以看到,每个构造函数本身都是一个对象,它有一个属性叫做prototype,它是一个对象。

      二、原型对象都包含一个指向构造函数的指针

            对于Object:

        

 

             对于Array:

        

            。。。。。。

            。。。。。。

            可以发现:每个构造函数的prototype属性都是个对象,这个对象都有一个属性constructor,它是个指针,并且指向构造函数本身。

       三、实例都包含一个指向原型对象的内部指针

            对于Object:

         

            对于Array:

         

            。。。。。。

            。。。。。。

          可以看到:实例都有一个属性叫做_proto_,它是个指针,指向原型对象。

     =================================================================

下面看一个例子:

1
2
3
4
5
6
7
8
9
function Dog (name) {
    this.name = name;
    this.type = 'Dog'
}
Dog.prototype.speak = function () {
  alert('wang');
}
var doggie = new Dog('jiwawa');
doggie.speak();  //wang 

   以上代码定义了一个构造函数 Dog(),  Dog.prototype 指向的原型对象,其自带的属性construtor又指回了 Dog,即  Dog.prototype.constructor == Dog. 实例doggie由于其内部指针指向了该原型对象,所以可以访问到 speak方法。

 

 

二、原型链

  前面我们说到,所有的实例有一个内部指针,指向它的原型对象,并且可以访问原型对象上的所有属性和方法。doggie实例指向了Dog的原型对象,可以访问Dog原型对象上的所有属性和方法;如果Dog原型对象变成了某一个类的实例 aaa,这个实例又会指向一个新的原型对象 AAA,那么 doggie 此时就能访问 aaa 的实例属性和 AA A原型对象上的所有属性和方法了。同理,新的原型对象AAA碰巧又是另外一个对象的实例bbb,这个实例bbb又会指向新的原型对象 BBB,那么doggie此时就能访问 bbb 的实例属性和 BBB 原型对象上的所有属性和方法了。

  这就是JS通过原型链实现继承的方法了。看下面一个例子:

//定义一个 Animal 构造函数,作为 Dog 的父类

function Animal () {
  this.superType = 'Animal';
}

Animal.prototype.superSpeak = function () {

  alert(this.superType);
}

function Dog (name) {

  this.name = name;
  this.type = 'Dog';
}
//改变Dog的prototype指针,指向一个 Animal 实例
Dog.prototype =  new Animal();
//上面那行就相当于这么写
//var animal = new Animal();
//Dog.prototype = animal;

Dog.prototype.speak = function () {

  alert(this.type);
}
var doggie = new Dog('jiwawa');
doggie.superSpeak(); //Animal

  解释一下。以上代码,首先定义了一个 Animal 构造函数,通过new Animal()得到实例,会包含一个实例属性 superType 和一个原型属性 superSpeak。另外又定义了一个Dog构造函数。然后情况发生变化,代码中加粗那一行,将Dog的原型对象覆盖成了 animal 实例。当 doggie 去访问superSpeak属性时,js会先在doggie的实例属性中查找,发现找不到,然后,js就会去doggie 的原型对象上去找,doggie的原型对象已经被我们改成了一个animal实例,那就是去animal实例上去找。先找animal的实例属性,发现还是没有 superSpeack, 最后去 animal 的原型对象上去找,诶,这才找到。

  

  这就说明,我们可以通过原型链的方式,实现 Dog 继承 Animal 的所有属性和方法。

  总结来说:就是当重写了Dog.prototype指向的原型对象后,实例的内部指针也发生了改变,指向了新的原型对象,然后就能实现类与类之间的继承了。(但是如果在重写原型对象之前,产生的实例,其内部指针指向的还是最初的原型对象。)

转载于:https://www.cnblogs.com/ytraister/p/10520331.html

你可能感兴趣的文章
复制文件到U盘错误0x80071AC3,请运行chkdsk并重试
查看>>
duilib之源码分析
查看>>
G_M_C_美食节
查看>>
详细解读MySQL中的权限
查看>>
HDOJ 1698 Just a Hook(线段树成段更新)
查看>>
SQL Server 内存中OLTP内部机制概述(二)
查看>>
Ext.Net学习笔记20:Ext.Net FormPanel 复杂用法
查看>>
php yii框架使用MongoDb
查看>>
cocos2dx中菜单menu 和 menuItem
查看>>
容器List之ArrayList详解
查看>>
GitHub的实现是否是基于此语言的支持网络编程性呢?
查看>>
四、java多线程核心技术——synchronized同步方法与synchronized同步快
查看>>
腾讯PHP工程师面试题两份
查看>>
训练1-U
查看>>
过去5年最受欢迎机器学习论文+代码速查
查看>>
AS3.0 XMLSocket简介
查看>>
列表边框column-rule
查看>>
单机部署RabbltMQ环境的操作记录
查看>>
HTML元素定义 ID,Class,Style的优先级
查看>>
【实数二分/前缀和维护】Best Cow Fences
查看>>