前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >前端day17-JS高级(原型对象)学习笔记

前端day17-JS高级(原型对象)学习笔记

原创
作者头像
帅的一麻皮
修改2020-05-07 18:01:48
4670
修改2020-05-07 18:01:48
举报
文章被收录于专栏:前端与Java学习前端与Java学习

01-面向对象编程

1.1-面向对象编程介绍
  • 1.理解什么是面向对象编程
    • 面向对象不是一门技术,而是一种解决问题的思维方式
    • 面向对象的本质是对面向过程的一种封装
  • 2.理解什么是对象
    • 对象的本质是程序代码与现实世界沟通的一座桥梁。它有两种函数
      • 对象:是一种数据类型(存储数据的容器),以键值对的形式存储数据
      • 对象:对现实世界实物的一种抽象。

代码语言:javascript
复制
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<script>
    /*1.面向对象编程与面向过程编程并不是一门技术,而是一种解决问题的思路和方式
            面向对象:注重的是结果
            面向过程:注重的是过程
     */
    //举例:做饭
    //1.1 面向过程:注重的是过程
    //买菜
    //洗菜
    //切菜
    //开火热锅
    //放油
    //把菜放到锅里炒
    //放盐,醋,酱油
    //把菜装到盘子里

    //1.2 面向对象:注重的是结果
    //不想自己做,找一个专业的对象来解决
    //地沟油一条街的厨师们

    /*是不是有了面向对象就不需要面向过程了呢?,不是,面向对象其实是对面向过程的一个封装 */

    /*2.理解什么是对象*/

    //2.1 对象是对单个实物的抽象     --------万物皆对象
    /*
    一台车: 特征:品牌 价格 颜色 轮子数量              行为:加速  刹车
    一个人: 特征:姓名 身高 年龄 性别                     行为:吃饭 睡觉 敲代码
    一条狗: 特征:品种 颜色  性别                            行为:拉屎 撒尿  打招呼
     */

    //2.2  对象是一个存储数据的容器    ------------键值对的形式存储数据
    var student = {
        name:'张三',
        age:18,
        eat:function (  ) {
            console.log ( "大吉大利,今晚吃鸡" );
        }
    }
    //2.3 如何寻找对象:名词提炼法
    //小明在公交车上牵着一条叼着热狗的狗
</script>
</body>
</html>

02-原型对象

2.1-构造函数的工作原理(引入原型对象)

  • 原型:任何构造函数在被创建的时候,系统都会自动帮我们创建一个与之对应的对象,称之为原型对象
    • 同时解决内存浪费与全局变量污染的问题
  • 谁可以访问原型对象中的成员(属性和方法)
    • 构造函数自身:构造函数名.prototype
    • 构造函数实例化的每一个对象:点语法直接访问
代码语言:javascript
复制
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>
    <script>
        /* 
            a. 原型 :每一个函数被创建的时候,系统都会自动创建与之对应的对象,称之为原型对象
            b. 作用: 解决 构造函数   (1)内存资源浪费 (2)全局变量污染
            c. 怎么用: (1)构造函数.prototype  (2)实例化对象直接访问
        */  
        
        //1.构造函数 :  调用一个函数使用了new关键字
        // 构造函数中的方法 弊端 : 浪费内存资源

        /*new关键字工作原理 
            //(1)创建空对象  {}
            //(2)this指向这个对象 this = {}
            //(3)执行赋值代码
            //(4)返回这个对象  return this
        */
        // function Person(name,age){
        //     //(1)创建空对象  {}
        //     //(2)this指向这个对象 this = {}
        //     //(3)执行赋值代码
        //     //(4)返回这个对象  return this
        //     this.name = name;
        //     this.age = age;
        //     this.sayHi = function(){
        //         console.log('猴赛雷呀,我爱坤坤哟');
        //     }
        // };

        // var p1 =  new Person('班长',28);
        // console.log(p1);
        // p1.sayHi();

        // var p2 = new Person('班花',18);
        // p2.sayHi();
        // //每一个对象的方法都不是同一个
        // console.log(p1.sayHi == p2.sayHi);//false


        //2. 使用全局函数 : 解决内存资源浪费问题

        //弊端 : 全局变量污染的问题

        // function fn(){
        //     console.log('猴赛雷呀,我爱坤坤哟');
        // };

        // function eat(){
        //     console.log('中午我要以面向对象的形式吃个饭'); 
        // };

        // function Person(name,age){
        //     //(1)创建空对象  {}
        //     //(2)this指向这个对象 this = {}
        //     //(3)执行赋值代码
        //     //(4)返回这个对象  return this
        //     this.name = name;
        //     this.age = age;
        //     this.sayHi = fn;
        //     this.eat = eat;
        // };

        // var p1 =  new Person('班长',28);
        // console.log(p1);
        // p1.sayHi();

        // var p2 = new Person('班花',18);
        // p2.sayHi();
     
        // console.log(p1.sayHi == p2.sayHi);//true



        //3.使用对象 解决 : (1)解决内存资源浪费  (2)全局变量污染
        //弊端 : 对象自身还是全局的,造成新的全局变量污染

        // var obj = {
        //     fn:function(){
        //         console.log('猴赛雷呀,我爱坤坤哟');
        //     },
        //     eat:function(){
        //         console.log('中午我要以面向对象的形式吃个饭'); 
        //     }
        // }
        

        // function Person(name,age){
        //     //(1)创建空对象  {}
        //     //(2)this指向这个对象 this = {}
        //     //(3)执行赋值代码
        //     //(4)返回这个对象  return this
        //     this.name = name;
        //     this.age = age;
        //     this.sayHi = obj.fn;
        //     this.eat = obj.eat;
        // };

        // var p1 =  new Person('班长',28);
        // console.log(p1);
        // p1.sayHi();

        // var p2 = new Person('班花',18);
        // p2.sayHi();
     
        // console.log(p1.sayHi == p2.sayHi);//true


        /*     4.使用原型 :             */
        
        /* 4.1 原型 : 每一个构造函数在声明的时候,系统会自动的创建一个与之对应的对象,
        称之为原型对象
        */
        function Person(name,age){
            this.name = name;
            this.age = age;
        };

        /*4.2 如何获取原型对象 
            每一个函数都有一个 prototype 属性,指向这个原型对象
        */
       console.log(Person.prototype);

       /* 
       4.3 既然原型是一个对象 : 用于存储数据
       */
      Person.prototype.sayHi = function(){
          console.log('坤坤我爱你');
          
      };

      /* 
      4.4 谁可以访问 原型中的成员(属性+方法)
        a. 构造函数自身 : 构造函数名.prototype
        b. 这个构造函数所创建(实例化)的每一个对象
      */
     // 实例化对象
     var p1 = new Person('班长',18);
     p1.sayHi();

     //实例化对象
     var p2 = new Person('班花',20);
     p2.sayHi();

     console.log(p1.sayHi === p2.sayHi);//true
     
    </script>
</body>
</html>

1.2- __proto__属性介绍

代码语言:javascript
复制
<script>
    /*  
    1. __proto__ 属性 : 属于实例化对象,指向构造函数的原型
    2. 作用 : 可以让每一个实例化对象访问自己的原型
    */
    
    //1. __proto__ 属性
    // 属于实例化对象,指向实例化这个对象的构造函数对应的原型
    function Student (name,age  ) {
        this.name = name;
        this.age = age
    };
    Student.prototype.sayHi = function (  ) {
        console.log ( "我的名字是" + this.name + "我的年龄是" + this.age );
    };
    var s1 = new Student('班长',38);
    console.log ( s1 );
    console.log ( s1.__proto__ === Student.prototype );//true

    //2.__proto__属性不是W3C的标准属性,所以实际开发中一般不会使用它来访问原型
    //官方文档参考:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Object/proto
    //2.1  不要通过实例对象的__proto__属性来修改原型(平时研究学习可以使用)
    s1.__proto__.type = '人类';
    //2.2 往原型添加属性方法,最好使用构造函数来访问
    Student.prototype.type = '人类';
</script>

1.3-constructor属性介绍

  • 1.constructor属性:属于原型对象,指向这个原型对应的构造函数
  • 2.constructor属性作用:可以得知某个实例对象,到底是由哪一个构造函数生成的
  • 3.注意点:如果对原型对象重新赋值,默认的constructor属性就会丢失
    • 解决方案:手动追加
代码语言:javascript
复制
<script>
    /* 
    1. constructor : 属于原型对象,指向自身对应的构造函数
    2. 作用 :可以让实例化对象被哪个构造函数创建
    3. 注意点 : 只有默认原型对象才有,原型重新赋值就会丢失。 需要重新找回
    */
    //1.constructor属性
    //属于原型对象,     指向这个原型对应的构造函数
    function Teacher (name,age  ) {
        this.name = name;
        this.age = age
    };
    Teacher.prototype.teach = function (  ) {
        console.log ( "我是老师,我的名字叫" + this.name + "我正在苦口婆心的教呀教………………" );
    };

    //查看构造函数的原型
    console.log ( Teacher.prototype );
    console.log ( Teacher.prototype.constructor === Teacher );//true

    //2.constructor属性作用:可以得知某个实例对象,到底是由哪一个构造函数生成的
    // 思考:下面这行代码结果
    var t1 = new Teacher('保健坤',38);
    console.log ( t1.constructor );//Teacher
    //思考:下面这行代码能够实例化对象
    var t2 = new Teacher.prototype.constructor('绿群',38);
    console.log ( t2 );

    //3.注意点:如果对原型对象重新赋值,默认的constructor属性就会丢失
    //解决方案:手动追加
    Teacher.prototype = {
        sayHi:function (  ) {
            console.log ( "一日为师终身为父" );
        },
        constructor:Teacher//重新找回constructor属性
    }
    console.log ( t1.constructor === Teacher );//true
    console.log ( Teacher.prototype.constructor === Teacher );//true

</script>

1.4-使用原型注意点

  • 1.一般哪些属性可以往原型中添加呢?
    • 构造函数实例化对象共有的数据
      • 例如:构造函数Dog用于创建狗对象,每一只狗都有saiHi叫的方法,此时可以添加到原型对象。而sex性别属性,不同的狗性别不同,此时就不能添加到原型中(否则实例化出来的狗性别都是固定的)
  • 2.对象访问成员变量的访问规则:如果自己有就访问自己的,自己没有就访问原型的
    • 成员变量:指的是对象的属性和方法的别称

3.原型对象可以重新赋值

  • 通过构造函数名.prototype来修改原型对象,不要使用实例化对象.proto来修改原型对象
  • 实例化对象访问原型中的成员变量,是访问修改前还是修改后,取决于这个对象是在修改前实例化还是修改
代码语言:javascript
复制
<script>
    /* 使用原型对象的注意点  */
    //1. 哪些属性可以往原型中添加:构造函数实例化对象共有的数据
    function Dog (  name,gender) {
        this.name = name;
        this.gender = gender;
    }
    //每一条狗都有叫的方法,那这个方法就可以写在原型中
    Dog.prototype.saiHi = function (  ) {
        console.log ( "汪汪汪~~" );
    }
    Dog.prototype.type = '哺乳动物';
    // Dog.prototype.gender = '母狗';//并不是每一只狗都是母狗,所以性别属性不能加到原型中

    var d1 = new Dog('来福','公狗');
    var d2 = new Dog('旺财','母狗');

    //2.对象访问成员变量(属性和方法)的访问规则:如果自己有就访问自己的,自己没有就访问原型的
    function Cat ( name,type ) {
        this.name = name;
        this.type = type;
        this.sayHi = function (  ) {
            console.log ( "我是构造函数中的sayHi" );
        }
    }
    Cat.prototype.sayHi = function (  ) {
        console.log ( "我是原型对象中的saiHi" );
    }

    var c1 = new Cat('群群','英短');
    console.log ( c1 );
    c1.sayHi();//我是构造函数中的sayHi

    //3.原型对象可以重新赋值
    /*a.通过构造函数名.prototype来修改原型对象,不要使用实例化对象.__proto__来修改原型对象
      b.实例化对象访问原型中的成员变量,是访问修改前还是修改后,取决于这个对象是在修改前实例化还是修改后
     */
    function Teacher ( name,age ) {
        this.name = name;
        this.age = age;
    }

    var t1 = new Teacher('利群',38);
    //3.1  注意:这个语法不是修改原型对象,而是给t1动态添加一个方法
    t1.sayHi = function (  ) {
        console.log ( "你们是我带过的最好的学生" );
    }
    console.log ( t1 );
    //3.2 注意:从语法上实例化对象可以修改原型对象,但是不建议这样写
    // t1.__proto__.sayHi = function (  ) {
    //     console.log ( "1111" );
    // }
    // console.log ( t1 );
    //3.3 修改原型对象,应该通过构造函数名.prototype来修改
    Teacher.prototype.sayHi = function (  ) {
        console.log ( "1111" );
    }

    var t2 = new Teacher('保健坤',38);
    console.log ( t2 );

    //3.4 原型对象重新赋值
    Teacher.prototype = {
        sayHi:function (  ) {
            console.log ( "我是修改后的原型对象的sayHi" );
        }
    };
    var t3 = new Teacher('隔壁老王',38);
    console.log ( t3 );
    t3.sayHi();//修改后
    t2.sayHi();//修改前
</script>

总结:构造函数、原型对象、实例化对象之间的三角关系

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 01-面向对象编程
    • 1.1-面向对象编程介绍
    • 02-原型对象
      • 2.1-构造函数的工作原理(引入原型对象)
        • 1.2- __proto__属性介绍
          • 1.3-constructor属性介绍
            • 1.4-使用原型注意点
              • 总结:构造函数、原型对象、实例化对象之间的三角关系
              相关产品与服务
              容器服务
              腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
              领券
              问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档