原型和原型链的理解(有图清晰明了)

记住一句话:万物皆对象

对于原型和原型链,我们要知道一下几个:函数对象,实例对象、原型对象

1)函数对象——就是平时称的对象;

2)实例对象——new出的对象或者{ };

3)原型对象——所有的函数对象都有一定有一个对应的原型对象,所有的原型对象都是被Object函数对象创建出来的。

一、原型

      原型是一个对象,是函数的一个属性prototype;

      通过该函数实例化出来的对象都可以继承得到原型上的所有属性和方法

      原型对象默认有一个属性constructor ,值为对应的构造函数;另外,有一个属性__proto__,值为Object.prototype

后文还有相关介绍!!!

二、原型链

        概念:(1)对象的创建(2)对象的组织结构(3)对象访问成员的规定

 在JavaScript中万物都是对象,对象和对象之间并不是独立存在的,对象和对象之间有一定关系。

        通过对象__proto__属性指向函数的原型对象(函数.prototype)一层一层往上找,直到找到Object的原型对象(Object.prototype)为止,层层继承的链接结构叫做原型链(通过proto属性形成原型的链式结构,专业术语叫做原型链)

后文还有相关介绍!!!

三、构造函数  

①构造函数本身也是函数

②构造函数,函数名尽量首字母要大写(为了区分普通函数和构造函数)

③构造函数中的this指向实例化对象

④构造函数需要使用new关键字调用

其中new关键字主要做了?

1.实例化了一个对象:

        eg: var 变量a= new son(1); 变量a表示实例化对象

2.将this指向实例化对象 eg:this—>a

3.将实例化对象的__proto__指向构造函数的原型对象上

4.将属性和方法添加到实例化对象上

         eg:this关键字添加

5.隐式的返回this

示例如下:

 四、以上之间的关系

1、这个图很重要:不管代码怎么变,实质性的东西都是图中所发展出来的

我们通过一个图来表示它们之间的联系,后面有相关解析:

  function Str(sprot,prise){
        this.mysprot=sprot;
        this.myprise=prise;
        this.say=function(){
            console.log("实例化对象上的方法");
        }
      }
      var s1=new Str("篮球",20);//实例化对象s1
      var s2=new Str("羽毛球",30);//实例化对象s2

1、我们要谨记一个源头:Function函数对象自动产生第一个对象

2、除Function函数对象之外,所有的函数对象都是由Function函数对象创建的。

3、Function会自动创建出很多函数对象出来

4、Function自动创建的第一个对象是Object对象函数,Function还会自动创建出的函数对象有:Object、window、Date等一系列的内置函数对象,我们自己写的函数对象也是Function创建的。

          其中我们可以根据代码知道:Object和我们自己设定的Show函数都是由Function创建出来的

        注意:Math不是函数对象,是实例对象

5、所有的函数对象都一定有一个对应的原型对象,所有的原型对象都是被Object函数对象创建的

6、所有的函数对象中都有一个名字叫prototype的引用类型变量,该引用类型变量是函数对象的成员,它的值是对应的原型对象的引用值,即prototype指向原型对象

7、所有的原型对象中都有一个名为constructor引用类型变量,该引用类型变量是原型对象的成员,该引用类型变量的值是对应的函数对象的引用值,即constructor指向函数对象

8、实例对象是被对应的函数对象(new出来的那个函数)创建的。

9、所有对象中都有一个名为__proto__的引用类型变量,该引用类型变量是对象的成员

10、Function函数对象中__proto__指向Function原型对象

11、Object函数对象中__proto__值为null。

1、对象中的__proto__的值是哪个对象的引用值?即指向哪个对象?分三种

(1)Function函数对象中的__proto__指向Function原型对象

(2)Object原型对象中__proto__的值为null

(3)除Function函数对象和Object原型对象之外,对象中的__proto__指向~~~谁创建了__proto__所属的对象,就指向谁的原型对象

2、对象访问成员的过程:

1)当前对象中如果有该成员就该到该成员,访问结束;

2)当前对象中如果没有该成员,则到__proto__指向的对象中找到成员,找到就结束,如果没有找到,就继续通过__proto__指向的对象中去找。

一个对象中如果有prototype,则该对象一定是函数对象,如果对象为函数对象,则其中一定有proyotype

一个对象中如果有constructor,则该对象一定有原型对象,如果对象为原型对象,则其中一定有constructor

2、prototype、__proto__、 constructor三者之间的关系

prototype :原型(原型对象)指向的都是原型

__proto__:指向的都是原型

constructor:原型上的属性:指向的是构造函数

①每个对象都有一个隐式的属性(__proto__),属性值本质上就是一个普通的对象

②每个函数对象都有一个原型属性(prototype),属性值本质上就是一个普通的对象

③每个对象的__proto__指向构造函数的原型对象(prototype)

④原型对象上有constrctor属性,指向构造函数

      //万物皆对象,实例化也是一个对象,看它是否指向构造函数Str的prototype原型对象,实例化对象是由构造函数创建的
      console.log(s1.__proto__);//指向str的原型对象
      console.log(Str.prototype);//指向str的原型对象
      console.log(s1.__proto__ === Str.prototype);//true

      console.log(s2.__proto__);//指向str的原型对象
      console.log(Str.prototype);//指向str的原型对象
      console.log(s2.__proto__ === Str.prototype);//true

      //Str也是一个对象,有一个隐式的属性(__proto__),构造函数的原型对象是由Object创建的
      console.log(Str.prototype.__proto__);//指向Object的原型对象
      console.log(Object.prototype);//指向Object的原型对象
      console.log(Str.prototype.__proto__ === Object.prototype);//true

      //Object也是一个对象,有一个隐式的属性(__proto__),Object的原型对象__proto__ 为null
      console.log(Object.prototype.__proto__);//null,指向为空

3、实战结论

1、Object的原型对象中的成员,可以所有对象访问,Object是原型链的尽头,Object原型对象通过Object.prototype得到。

        示例:Object.prototype.show(){.......},所有对象就可以访问show函数里面的......。

2、所有的原型对象都是由Object函数对象创建的。

3、new 出的对象是由函数对象创建的。

4、所有的对象中都自带属性__proto__,__proto__指向一个对象

5、Object原型对象中__proto__特殊,它的值为null

6、Function函数对象中__proto__特列,它指向Function原型对象。

7、所有的函数对象中都有prototype属性,原型对象和new 出来的对象中没有

8、prototype总是指向对应的原型对象。

代码如下:

 function Fun(){
            this.a=1;
        }
        Fun.prototype={     //fun的原型对象
           aa:10,
           constructor:Fun  //做一个指向,不然后面有关的constructor都为false,可以知道Fun是由Fun构造出来的
        }
        var fn1=new Fun();//实例化创建一个新函数,实例化对象为fn1
        console.log(fn1.aa);  //10
        
        console.log(Object.prototype);
        console.log(Fun.prototype.__proto__);
        console.log(Object.prototype.__proto__); //null
        //访问原型有两种方式:一是通过实例方式,二是通过构造函数
        console.log(fn1.__proto__ === Fun.prototype);//true
        //Object.prototype是Fun.prototype的父亲,Fun.prototype是fn1.__proto__的父亲
        //Object.prototype是原型的终点
        console.log(Object.prototype === fn1.__proto__);//false
        console.log(Object.prototype === fn1.__proto__.__proto__);//true
          //等于console.log(Object.prototype === Fun.prototype.__proto__);

        //实例上的能拿到原型上的属性和方法
        console.log(Fun.prototype.constructor === Fun);//true(若没有做constructor指向,则为false,没有定义)
        console.log(fn1.constructor === Fun);//true(若没有做donstructor指向,则为false,没有定义)
        console.log(Object.prototype.constructor === Object);//true
        console.log(Object.getPrototypeOf(fn1) ===  Fun.prototype);//true

猜你喜欢

转载自blog.csdn.net/qq_64180670/article/details/127890762