美文网首页
对原型与原型链的理解

对原型与原型链的理解

作者: 你为什么无理取闹 | 来源:发表于2018-07-09 20:21 被阅读0次

原型对象

javascript语言是一种面向对象的语言,它没有"子类"和"父类"的概念,里面所有的数据类型都是对象,如何将这些对象联系起来呢?

Brendan Eich在考虑设计继承机制的时候,参考了C++和JAVA使用new命令,通过调用类的构造函数生成实例的方式,将new命令引入javascript。

C++的写法是:

ClassName *object = new ClassName(param);

Java的写法是:

Person person = new Person();

但是,javascript里面没有“类”这个概念,那么,Brendan Eich决定直接在new后面跟一个构造函数,来生成实例。

构造函数是什么?构造函数与其他函数唯一的区别在于调用方式不同。任何函数只要通过new来调用就可以作为构造函数,它是用来创建特定类型的对象。

下面定义一个构造函数Female:

 1    function Female(name){
2           this.name = name;
3           this.sex = 'female';  
4    }

通过new命令来生成一个person实例:

var person1 = new Female("Summer")

这里,构造函数Female就是实例对象person1的原型!!!Female里的this关键字就指的是person1这个对象!

new出来的person1对象此时已经和Female再无联系了!也就是说每一个new出来的实例都有自己的属性和方法的副本,是独立的的!修改其中一个不会影响另一个!

var person1 = new Female("Summer");
var person2 = new Female("Lily");

person2.sex = 'male';

console.log(person1.sex)      // female
console.log(person2.sex)      // male

但是,我们希望构造函数中的sex属性是一个共有属性,那么此时用这样的方法,每个实例中都有一个相同的sex属性,会造成资源极大的浪费!

那么原型对象就即将登场了!Brendan Eich决定给每一个构造函数都设置一个prototype属性,这个属性就指向原型对象。其实原型对象就只是个普通对象,里面存放着所有实例对象需要共享的属性和方法!所以,我们把需要共享的放到原型对象里,把那些不需要共享的属性和方法存在在构造函数里!

那么上面的代码可改写如下:

  function Person(name,age){
            this.name = name;
        }
        Person.prototype.sex = 'female';

        var person1 = new Person("Summer");
        var person2 = new Person("Lily");
        
        console.log(person1.sex)      // female
        console.log(person2.sex)      // female

        Person.prototype.sex = 'male';

        console.log(person1.sex)      // male
        console.log(person2.sex)      // male

可以看出,修改prototype属性会影响它的所有实例的sex的值!!

实例一旦创建出来就会自动引用prototype对象的属性和方法!所以实例对象的属性和方法一般分为两种:一种是自身的,一种是引用自prototype的。

具体实现是这样的:

  每当代码读取某个对象的某个属性的时候,都会执行一次搜索。首先从对象实例本身开始,如果在实例中找到了该属性,则返回该属性的值,如果没有找到,则顺着**原型链指针**向上,到原型对象中去找,如果如果找到就返回该属性值。

这里要提一点,如果为对象实例添加了一个属性与原型中同名,则该属性会屏蔽掉原型中的同名属性,不会去修改它!使用delete可以删除实例中的属性(提到delete那要插一句delete只能删除对象下的属性,不能删除变量和参数!)

原型链

事实上,js里完全依靠"原型链"(prototype chain)模式来实现继承。

上面说完原型对象。下面要扒一扒proto、prototype、constructor

proto:事实上就是原型链指针!!

prototype:上面说到这个是指向原型对象的

constructor:每一个原型对象都包含一个指向构造函数的指针,就是constructor

继承实现方式:

为了实现继承,proto会指向上一层的原型对象,而上一层的结构依然类似,那么就利用proto一直指向Object的原型对象上!Object.prototype.proto = null;表示到达最顶端。如此形成了原型链继承。

下面有个图解非常经典,我自己也手画了一遍去理解,真的非常有效~

image

大致总结一下就是:

Object是作为众多new出来的实例的基类 function Object(){ [ native code ] }

Function是作为众多function出来的函数的基类 function Function(){ [ native code ] }

构造函数的proto(包括Function.prototype和Object.prototype)都指向Function.prototype

原型对象的proto都指向Object.prototype

Object.prototype.proto指向null

相关文章

  • JavaScript 原型、原型链与原型继承

    原型,原型链与原型继承 用自己的方式理解原型,原型链和原型继承 javascript——原型与原型链 JavaSc...

  • 廖雪峰JS小记

    (function(){})() 原型,原型链 浅谈Js原型的理解JS 原型与原型链终极详解 对象 对象:一种无序...

  • 再来看一次JS继承

    原型链继承 理解原型链的概念 用一张图来理解原型链再合适不过了。 总结概括JS红宝书上对原型链的概念:每个函数都有...

  • 对原型与原型链的理解

    原型对象 javascript语言是一种面向对象的语言,它没有"子类"和"父类"的概念,里面所有的数据类型都是对象...

  • 对原型与原型链的理解

    最开始想要直观的理解请直接参考阮一峰老师博客关于继承的讲解:http://www.ruanyifeng.com/b...

  • 个人对面向对象的理解

    我对原型和原型链式这样理解的,原型和原型链在javascript当中主要用来体现对象 与属性之间的关系,它主要应用...

  • 原型和原型链

    今天发现一张特别好的图(↑↑↑上图↑↑↑),对原型和原型链的理解特别直观友好。 原型和原型链 基础储备:每个 JS...

  • 原型、原型链、继承 | JavaScript

    原型与原型链 基本概念 关于原型和原型链的知识,首先来理解下以下几个知识点: 所有引用类型(Object、Arra...

  • 来来来,通俗的理解一下原型,原型链......

    今天,在网上看到这个讲原型和原型链的通俗的分析,感觉对理解还是有帮助的,特此分享: 原型链理解起来有点绕了,网上资...

  • 原型与原型链的理解

    【本文章系转载】 最开始想要直观的理解请直接参考阮一峰老师博客关于继承的讲解:http://www.ruanyif...

网友评论

      本文标题:对原型与原型链的理解

      本文链接:https://www.haomeiwen.com/subject/aytiuftx.html