js奥义:原型与原型链(1)

要弄懂原型链,首先应先明白prototype原型对象、__proto__、对象三者之间的关系。javascript

引入构造函数的相关定义:java

  构造函数是一种比较特殊的函数,用于批量实例化对象。通俗一点说,构造函数是用于生成对象的模板es6

因为工厂模式在实例化对象时会存在同一功能代码在内存中开辟不一样内存空间从而形成内存空间浪费的问题,更多的人选择使用构造函数来实例化对象,es6中引进的class关键字正是基于构造函数的思想浏览器

构造函数的本质上是将对象中一些公共的方法和属性 抽取出来,而后将这个函数封装成可复用的构造函数.函数

 构造函数的特色(与工厂函数相比较):    this

    a. 函数名首字母大写;spa

    b.  函数体内没有关键字new,在实例化一个对象时会使用关键字new;prototype

    c.  构造函数体内的this指代当前实例化对象;对象

    d.   函数体内没有关键字return。blog

 function Fn() {
            this.n = 20
        }
        Fn.prototype.say= function() {
            console.log(this.n)
        }
        var deb = new Fn()

  

 构造函数的new关键字在实例化对象时会作如下四件事:

  a.如今内存中开辟一块内存空间(new obj);

  b.让构造函数体内的this指向这个对象   (于是,this指代当前对象);

  c.将构造函数体内的属性和方法赋值给这个这个对象;

  d.返回这个对象 (于是,构造函数体内没有return关键字)

为了区别对待,如下将构造函数称为父类,将实例化对象称为子类。

一:原型

  1.定义

 每个函数身上都有一个prototype(原型),因为这个prototype的值是一个对象类型,于是又叫作原型对象,ptototype属性是函数独有的属性!

  2.原型的做用

  原型对象的做用一般用来共享父类的方法,因为方法是函数,本质上也是一个对象,而对象的内存地址保存在堆空间里,如同工厂模式通常,多个内存空间存放相同的代码,会形成大量空间被占用,于是将公有的方法添加在父类的prototype上,也就是写入了同一对象上,调用的时候也就避免了多个空间存放同一代码的错误示范,而因为父类的属性的值是基本类型,所占内存较少,因此咱们每每将其添加到父类函数体的内部。

  function Fn() {
            this.n = 20
        }
        Fn.prototype.sing = function() {
            console.log(this.n)
        }
        var deb = new Fn()
        var deb2 = new Fn()
        console.log(deb.sing === deb2.sing) //true

 二:__proto__

  与函数的prototype属性不一样,每个obj的对象都有一个__ptoto__属性,这个__proto__属性隐式的指向了这个子类的的构造函数的prototype属性!可是这个__proto__属性是不可见的,这也就是为何将其称做是隐式的,不过好在浏览器的支持下,它被定义为__proto__

  若是看到这里,但愿你再好好思考一下 ”万物皆对象“这句话的含义

  从父类的角度看,子类的_proto_属性隐式指向了它的父类的prototype对象;从子类的角度看,子类自身的__proto__属性指向了它的父类的prototype属性

  假如咱们对比父类的prototype与子类的__proto__属性:

        console.log(Fn.prototype === deb.__proto__)//true

  理解了这一点,就能够明白为何构造函数添加在其原型对象上的方法,实例化对象能够共享使用了:由于构造函数的prototype属性指向的实例化对象的__proto__属性指向是同一个对象,也就是父类的prototype对象

这样,就具有了深刻理解原型链的条件。

相关文章
相关标签/搜索