zoukankan      html  css  js  c++  java
  • JavaScript原型链

    什么是原型链?

    是一种关系,实例对象和原型对象之间的关系,关系是通过原型来联系的

    或者是原型链就是创建一个构造函数,它会默认生成一个prototype属性并指向原型对象。使用下一个构造函数的原型对象作为这个构造函数的实例。

     1     //构造函数
     2     function Person(name,age) {
     3       //属性
     4       this.name=name;
     5       this.age=age;
     6       //在构造函数中的方法
     7       this.eat=function () {
     8         console.log("吃好吃的");
     9       };
    10     }
    11     //添加共享的属性
    12     Person.prototype.sex="男";
    13     //添加共享的方法
    14     Person.prototype.sayHi=function () {
    15       console.log("您好啊,怎么这么帅,就是这么帅");
    16     };
    17     //实例化对象,并初始化
    18     var per=new Person("小明",20);
    19     per.sayHi();
    20     //如果想要使用一些属性和方法,并且属性的值在每个对象中都是一样的,方法在每个对象中的操作也都是一样,那么,为了共享数据,节省内存空间,是可以把属性和方法通过原型的方式进行赋值
    21 
    22     console.dir(per);//实例对象的结构
    23     console.dir(Person);//构造函数的结构
    24 
    25     //实例对象的原型__proto__和构造函数的原型prototype指向是相同的
    26 
    27     //实例对象中的__proto__原型指向的是构造函数中的原型prototype
    28     console.log(per.__proto__==Person.prototype);
    29     //实例对象中__proto__是原型,浏览器使用的
    30     //构造函数中的prototype是原型,程序员使用的

    原型的指向是否可以改变

     1     //人的构造函数
     2     function Person(age) {
     3       this.age=10;
     4     }
     5     //人的原型对象方法
     6     Person.prototype.eat=function () {
     7       console.log("人的吃");
     8     };
     9     //学生的构造函数
    10     function Student() {
    11 
    12     }
    13     Student.prototype.sayHi=function () {
    14       console.log("嗨,小苏你好帅哦");
    15     };
    16     //学生的原型,指向了一个人的实例对象
    17     Student.prototype=new Person(10);
    18     var stu=new Student();
    19     stu.eat(); // 人的吃
    20     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

    原型指向改变如何添加方法和访问

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

     
     1        //人的构造函数
     2        function Person(age) {
     3          this.age=age;
     4        }
     5        //人的原型中添加方法
     6        Person.prototype.eat=function () {
     7          console.log("人正在吃东西");
     8        };
     9        //学生构造函数
    10        function Student(sex) {
    11          this.sex=sex;
    12        }
    13     
    14        //改变了原型对象的指向
    15        Student.prototype=new Person(10);
    16        //学生的原型中添加方法----先在原型中添加方法
    17        Student.prototype.sayHi=function () {
    18          console.log("您好哦");
    19        };
    20        var stu=new Student("男");
    21        stu.eat();//人正在吃东西
    22        stu.sayHi();//您好哦

    或者是这样

     
     1     //指向改变了
     2     Person.prototype = {
     3       eat: function () {
     4         console.log("吃");
     5       }
     6     };
     7     //先添加原型方法
     8     Person.prototype.sayHi = function () {
     9       console.log("您好");
    10     };
    11     var per = new Person(10);
    12     per.sayHi();//您好

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

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

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

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

    最后来看一个很神奇的原型链

    原型链:实例对象和原型对象之间的关系,通过proto来联系

     
    1 <div id="dv"></div>
    2 <script>
    3   var divObj=document.getElementById("dv");
    4   console.dir(divObj);
    5 
    6   //divObj.__proto__---->HTMLDivElement.prototype的__proto__--->HTMLElement.prototype的__proto__---->Element.prototype的__proto__---->Node.prototype的__proto__---->EventTarget.prototype的__proto__---->Object.prototype没有__proto__,所以,Object.prototype中的__proto__是null
    7 
    8 </script>
     
  • 相关阅读:
    使用vue-cli搭建SPA项目
    NodeJS的环境搭建+传统ELmentui+vue开发
    vue路由
    Vue基础语法(样式绑定,事件处理,表单,Vue组件)
    动态规划 | 保留重复元素的LCS 1045
    动态规划 | 1007 最大连续子序列和
    数学问题 | 质因数分解:1096
    数学问题 | 连续质因数分解:1096
    数据结构 | 哈希表二次探查法 : 1078
    数学问题 | 1015 进制转换与素数问题
  • 原文地址:https://www.cnblogs.com/Object-L/p/12162500.html
Copyright © 2011-2022 走看看