2-面向对象3大特性 创建对象的4种方式 构造函数注意点 构造函数的原型对象(使用方法/注意事项) 实例/实例化 实例/原型成员

面向对象的三大特性

  • 封装: 在JS中使用对象封装一些变量和函数
    • 好处: 信息隐蔽, 方便扩展维护, 提高代码的复用性
  • 继承: 一个类(对象)获取另一个类(对象)的属性和方法的一种形式
    • 面向对象语言定义: 是否有类的概念(c++ Java)
    • JS没有类的概念, JS从这个角度说不是面向对象语言. 但面向对象具有继承特性, 可以说JS支持面向对象语言
  • 多态: 同一操作, 作用于不同对象, 会产生不同行为(解释)
    • 实现: JS天生就具有多态的特性(弱类型语言)

创建对象的方式

  1. 字面量的方式

     var student = {
         name: 'zs',
         age: 16,
         class: '一分钟精通JS'
     }
     //一个班级有N个学生, 通过字面量形式, 需要创建N个学生对象
     //问题: 创建多个同类型的对象时, 大量代码冗余(重复代码)
     //价值: 只需要创建简单的几个对象
    
  2. 内置的构造函数

    • 系统内置的构造函数: Object | Array | Math | Date | Function | String | Number | Boolean

        var stu = new Object();
        stu.name= 'zs';
        stu.age= 16;
        stu.class=  '一分钟精通JS';
        //跟字面量的方式差不多, 问题也是一样-->创建对象的相同部分进行函数封装(简单工厂)
      
  3. 简单的工厂方式: 类似函数封装, 相同的不变, 不同的作为参数传进来

     function person(){
         var stu = new Object();
         stu.name= 'zs';
         stu.age= 16;
         stu.class=  '一分钟精通JS';
         //返回该对象
         return stu;
     }
     var stu1 = person();
     var stu2 = person();    
     //问题: 两个学生信息都一样
    
     //优化如下: 不同的信息当做参数传进来                
     function person(name, age, classes){
         var stu = new Object();
         stu.name= name;
         stu.age= age;
         stu.class=  classes;
         return stu;
     }               
     function dog(name, age, classes){
         var dog = new Object();
         dog.name= name;
         dog.age= age;
         dog.class= classes;
         return dog;
     }
     var stu3 =  person('zs', 16, '一分钟精通JS' );   
     var dog = dog('wangCai', 5 , '骑单车');
     console.log(stu3 == dog);    //false
     //问题: 创建不同类型的对象时, 无法分辨其类型       
    
  4. 自定义构造函数-参照上一章构造函数创建对象

    • 定义

      • 自己定义的构造函数(首字母大写)-通过this设置属性/方法-使用new调用构造函数创建对象
    • 执行过程

      1. 通过new关键字调用构造函数,构造函数内部默认创建一个新对象
      2. 将这个新对象赋值给this
      3. 通过this设置属性和方法
      4. 默认返回新创建对象
    • 返回值

      • 如果没有显示return, 默认返回构造函数内部新创建的对象
      • 若写了返回值, 要看具体情况
        • 如果返回值类型的数据, 就直接忽略, 返回内部新创建的对象
        • 若返回引用类型的数据, 直接返回该数据(会覆盖内部新创建的对象)
    • 自定义构造函数(区别于简单的工厂函数)

      1. 函数名首字母大写
      2. 自定义构造函数内部会默认创建一个对象-默认将这个对象赋值给this
      3. 默认会返回新创建的对象
      4. 创建不同类型的对象时, 可以分辨其类型

构造函数注意事项

  1. 函数传值: 函数当做参数传进构造函数
  2. 判断对象的类型
    • 对象 instanceof 构造函数: 判断指定对象是否由某个构造函数创建出来
  3. 获取对象类型: 构造器属性obj.constructor
  4. 构造函数调用-区别于函数调用
    • new关键字: 默认创建/返回对象

    • 构造函数: 对这个对象进行一些初始化的操作(将创建对象赋值给this, 通过this绑定属性/方法)

         function Person(name) {
              // this = obj;
      
              console.log(this);
              this.name = name;
              // return obj;
         }
        var p1 = new Person('zs');
      
        // 构造函数也是一个函数
        var p2 = Person('ls'); // 可以这样写,但是不建议这样做
        console.log(p2); // undefined, 直接调用构造函数,this指向window
      
       //分析打印结果
       <script>
            function fn(){
                var t = 1;
                this.x = 3;
                document.write(t);
                document.write(this.x);
            }
            var obj = new fn();
            document.write(obj.x);
            document.write(fn());
        </script>
      

构造函数的原型对象

  1. 原型对象定义

    • 在构造函数创建出来时, 系统默认会创建一个对象与这个构造函数相关联, 这个对象称为该构造函数的原型对象


      构造函数的原型对象
  2. 作用

    • 使用构造函数创建出来的对象, 默认就可以使用该构造函数原型对象的属性和方法
  3. 访问原型对象: 构造函数.prototype

  4. 设置原型对象: 构造函数.prototype.name = 'name1';

    • 原型对象本质也是一个对象, 可以利用对象的动态特性设置原型对象
  5. 约定

    • 该对象构造函数的原型对象
    • 构造函数的原型对象(原型) | 对象的原型对象(原型)

实例与实例化

  • 实例: 通过构造函数创建出来的对象.
    • 一般说: XX是构造函数的实例
    • 实例成员: 实例属性+实例方法
  • 实例化: 通过构造函数创建对象的过程
  • 注意点
    • 实例对象可以访问实例成员和原型成员, 但是不能够访问静态成员
    • 构造函数在访问静态方法时, 内部的this指向的是构造函数自己, 不能访问到实例对象的成员
    function Person() {
        this.name = "张三";   //实例属性
        var age = 18;       //私有变量
        this.showName = function () {       //实例方法
            console.log(this.name);
        }
        this.showAge = function () {    //特权方法
            console.log(age);   
        }
    }   
    Person.prototype.show = function () {   //原型方法
        console.log(this.name);
    }   
    Person.des = function () {  //静态方法
        console.log(this.name);
    }   
    var p1 = new Person();

    p1.showName();  //张三
    p1.showAge();   //18
    p1.show();      //张三
    //p1.des();       //undefined ? 报错(Y)
    Person.des();     //undefined ? 报错 ? 张三 ?Person(Y)

原型的使用方法

  • 利用对象的动态特性设置原型对象
    • 提供一个构造函数
    • 设置原型对象的成员(原型属性+原型方法)
      • 添加成员: 构造函数.prototype.name = "name1";
      • 修改成员: 构造函数.prototype.name = "name2";
      • 删除成员: delete 构造函数.prototype.name;
  • 替换原型对象: 自己定义的对象赋值给原型对象
    1. 替换原型对象之前创建的对象和替换之后创建的对象,他们的原型对象不是同一个对象
    * 注意点: 获取替换原型对象的属性与替换之前原型对象的属性值不相等
    * 建议: 最好在替换原型对象之后, 再创建对象
    
    1. 修正构造器属性

使用原型对象的注意事项

  • 访问原型对象的属性-方式
    1. 对象.属性(就近原则)
      • 首先查找自身是否有该属性, 若有就直接使用
      • 若没有就查找该对象原型对象的属性, 若有就直接使用
      • 再没有就返回undefined或报错
    2. 构造函数.prototype.属性
  • 设置原型对象
    • 通过对象.属性设置属性
      • 如果有这个属性就是修改, 没有这个属性就是添加属性, 不会修改原型对象的属性
    • 设置原型对象的属性
      • 通过构造函数.prototype.属性或者替换原型
      • 如果原型属性是引用类型的数据, 可以通过对象.属性.属性的方式修改

构造器属性相关

  • constructor属性: 指向与之对应的构造函数
  • 对象.constructor: 访问的是原型对象的constructor属性

__proto__属性

  • 定义
    • 构造函数创建出来的对象, 默认就有一个__proto__属性, 该属性指向该对象对应的构造函数的原型对象
  • 访问原型对象-方式
    1. 构造函数.prototype
    2. 对象.__proto__
      • 注意点: 在正式开发中, 不建议使用. 该属性不是ES标准, 是部分浏览器厂商方便调试程序


        __proto__和constructor结构关系图

hasOwnProperty()

  • 语法: 对象.hasOwnProperty("属性名")
  • 定义: 判断对象中是否存在指定的属性(实例属性)/ES5 中判断对象的自有属性(hasOwnProperty)
  • in区别: in判断对象中是否存在指定的属性(不区分实例属性/原型属性)

isPrototypeOf()

  • 语法: 构造函数.protoType.isPrototypeOf(对象)
  • 定义: 判断一个对象是否是指定对象的原型对象(判断原型对象是否在整条原型链上)
  • instanceof区别: instanceof判断一个对象是否是指定构造函数的实例对象
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,324评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,303评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,192评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,555评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,569评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,566评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,927评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,583评论 0 257
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,827评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,590评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,669评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,365评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,941评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,928评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,159评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,880评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,399评论 2 342

推荐阅读更多精彩内容