JavaScript原型链

作者: nomooo | 来源:发表于2019-03-18 23:15 被阅读23次

什么是原型链?
是一种关系,实例对象和原型对象之间的关系,关系是通过原型来联系的
或者是原型链就是创建一个构造函数,它会默认生成一个prototype属性并指向原型对象。使用下一个构造函数的原型对象作为这个构造函数的实例。

    //构造函数
    function Person(name,age) {
      //属性
      this.name=name;
      this.age=age;
      //在构造函数中的方法
      this.eat=function () {
        console.log("吃好吃的");
      };
    }
    //添加共享的属性
    Person.prototype.sex="男";
    //添加共享的方法
    Person.prototype.sayHi=function () {
      console.log("您好啊,怎么这么帅,就是这么帅");
    };
    //实例化对象,并初始化
    var per=new Person("小明",20);
    per.sayHi();
    //如果想要使用一些属性和方法,并且属性的值在每个对象中都是一样的,方法在每个对象中的操作也都是一样,那么,为了共享数据,节省内存空间,是可以把属性和方法通过原型的方式进行赋值

    console.dir(per);//实例对象的结构
    console.dir(Person);//构造函数的结构

    //实例对象的原型__proto__和构造函数的原型prototype指向是相同的

    //实例对象中的__proto__原型指向的是构造函数中的原型prototype
    console.log(per.__proto__==Person.prototype);
    //实例对象中__proto__是原型,浏览器使用的
    //构造函数中的prototype是原型,程序员使用的

原型的指向是否可以改变

    //人的构造函数
    function Person(age) {
      this.age=10;
    }
    //人的原型对象方法
    Person.prototype.eat=function () {
      console.log("人的吃");
    };
    //学生的构造函数
    function Student() {

    }
    Student.prototype.sayHi=function () {
      console.log("嗨,小苏你好帅哦");
    };
    //学生的原型,指向了一个人的实例对象
    Student.prototype=new Person(10);
    var stu=new Student();
    stu.eat(); // 人的吃
    stu.sayHi(); //Uncaught TypeError: stu.sayHi is not a function

从上面代码可以看得出来:

  • 原型指向可以改变
    实例对象的原型proto指向的是该对象所在的构造函数的原型对象
    构造函数的原型对象(prototype)指向如果改变了,实例对象的原型(proto)指向也会发生改变
    实例对象和原型对象之间的关系是通过proto原型来联系起来的,这个关系就是原型链

原型最终指向了哪里?

    function Person() {

    }
    Person.prototype.eat=function () {
      console.log("吃东西");
    };

    var per=new Person();
    console.dir(per);
    console.dir(Person);

    //实例对象中有__proto__原型
    //构造函数中有prototype原型
    //prototype是对象
    //所以,prototype这个对象中也有__proto__,那么指向了哪里
    //实例对象中的__proto__指向的是构造函数的prototype
    //所以,prototype这个对象中__proto__指向的应该是某个构造函数的原型prototype

    //Person的prototype中的__proto__的指向
    //console.log(Person.prototype.__proto__);

    //per实例对象的__proto__------->Person.prototype的__proto__---->Object.prototype的__proto__是null

    console.log(per.__proto__==Person.prototype);//true
    console.log(per.__proto__.__proto__==Person.prototype.__proto__);//true
    console.log(Person.prototype.__proto__==Object.prototype);//true
    console.log(Object.prototype.__proto__);//null

原型指向改变如何添加方法和访问
如果原型指向改变了,那么就应该在原型改变指向之后添加原型方法

       //人的构造函数
       function Person(age) {
         this.age=age;
       }
       //人的原型中添加方法
       Person.prototype.eat=function () {
         console.log("人正在吃东西");
       };
       //学生构造函数
       function Student(sex) {
         this.sex=sex;
       }
    
       //改变了原型对象的指向
       Student.prototype=new Person(10);
       //学生的原型中添加方法----先在原型中添加方法
       Student.prototype.sayHi=function () {
         console.log("您好哦");
       };
       var stu=new Student("男");
       stu.eat();//人正在吃东西
       stu.sayHi();//您好哦

或者是这样

    //指向改变了
    Person.prototype = {
      eat: function () {
        console.log("吃");
      }
    };
    //先添加原型方法
    Person.prototype.sayHi = function () {
      console.log("您好");
    };
    var per = new Person(10);
    per.sayHi();//您好

实例对象的属性和原型对象那个中的属性重名

  • 没有这个属相的情况下
    function Person(age,sex) {
      this.age=age;
      this.sex=sex;
    }
    Person.prototype.sex="女";
    var per=new Person(10,"男");
    console.log(per.sex);
    console.log(per.fdsfdsfsdfds);

因为JS是一门动态类型的语言,对象没有什么,只要点了,那么这个对象就有了这个东西,没有这个属性,只要对象.属性名字,对象就有这个属性了,但是,该属性没有赋值,所以,结果是:undefined

  • 重名属性这个问题就相当于想改变原型对象中属性的值。
    直接通过原型对象:属性=值,就可以改变
   Person.prototype.sex="哦唛嘎的";
   per.sex="人";
   console.log(per.sex);//人

最后来看一个很神奇的原型链
原型链:实例对象和原型对象之间的关系,通过proto来联系

<div id="dv"></div>
<script>
  var divObj=document.getElementById("dv");
  console.dir(divObj);

  //divObj.__proto__---->HTMLDivElement.prototype的__proto__--->HTMLElement.prototype的__proto__---->Element.prototype的__proto__---->Node.prototype的__proto__---->EventTarget.prototype的__proto__---->Object.prototype没有__proto__,所以,Object.prototype中的__proto__是null

</script>

相关附加
JavaScript原型
JavaScript中原型的简单语法
JavaScript原型链
JavaScript中的继承

相关文章

  • 【javascript】继承

    javascript只支持实现继承,而且继承主要是依靠原型链来实现的。 原型链 javascript将原型链作为实...

  • js原型、原型链、继承的理解

    一、原型、原型链 原型是Javascript中的继承的基础,JavaScript的继承主要依靠原型链来实现的。 原...

  • javaScript原型链

    javaScript原型链概念JavaScript之继承(原型链)数据结构var Person = functio...

  • 原型、原型链

    (什么是原型、原型链?有什么作用) JavaScirpt深入之从原型到原型链 图解 Javascript 原型链 ...

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

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

  • javascript碎片知识001

    javascript中的对象(原型,原型链) 什么是原型? 原型是JavaScript中的继承的基础,JavaSc...

  • 面试题 Javascript

    介绍JavaScript的基本数据类型。 说说写JavaScript的基本规范? JavaScript原型,原型链...

  • JavaScript 基础知识点

    介绍JavaScript的基本数据类型。 说说写JavaScript的基本规范? JavaScript原型,原型链...

  • 原型和原型链篇

    原型和原型链 1.理解原型设计模式以及JavaScript中的原型规则 原型设计模式JavaScript是一种基于...

  • 原型链 完整版(JavaScript)

    原型链 完整版(JavaScript)

网友评论

    本文标题:JavaScript原型链

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