• JS面向对象设计-创建对象


    Object构造函数和对象字面量都可以用来创建单个对象,但是在创建多个对象时,会产生大量重复代码.

    1.工厂模式

    工厂模式抽象了创建具体对象的过程.由于ECMAScript无法创建类,我们用函数来封装以特定接口创建对象的细节.

    function createPerson(name, age, job) {
        var o = new Object();
        o.name = name;
        o.age = age;
        o.job = job;
        o.sayName = function() {
            console.log(this.name);
        }
        return o;
    }
    
    // 根据接收到的参数,构建一个包含三个属性一个方法的对象,并返回
    var person1 = createPerson("zhu", 26, "FE");
    

    ps. 工厂模式解决了创建多个相似对象的问题,却无法识别对象(对象的类型)

    2.构造函数模式

    用来创建特定类型的对象,比如Object/Array这样的原生构造函数,或者自定义构造函数(可以自定义对象类型的属性和方法).

    /* 1.没有显示创建对象
    *  2.直接将属性和方法赋值给this对象
    *  3.没有return语句
    *  4.首字母大写(区别于ECMAScript中其他函数,构造函数本身也是函数,只不过可以创建对象)
    */
    function Person(name, age, job) {
        this.name = name;
        this.age = age;
        this.job = job;
        this.sayName = function() {
            console.log(this.name);
        }
    }
    
    // 必须使用new操作符
    var person1 = new Person("zhu", 26, "FE");
    var person2 = new Person("liu", 23, "JAVA");
    

    2.1 调用该总种构造函数会经历四个步骤

    1. 创建一个新对象
    2. 将构造函数的作用域赋给新对象(因此this就指向了这个新对象)
    3. 执行构造函数中的代码(为这个新对象添加属性)
    4. 返回新对象

    2.2 对象类型

    1. person1,person2分别保存着Person的一个不同实例,两个对象都有constructor(构造函数)属性指向Person.

      person1.constructor == Person, person2.constructor == Person // true
      
    2. person1,person2既是Object实例也是Person实例.

      // 所有对象均继承自Object
      person1 instanceof Object, person1 instanceof Person // true
      person2 instanceof Object, person2 instanceof Person // true
      

    ps. 创建自定义构造函数意味着可以将它的实例标识为一种特定的类型.

    2.3 将构造函数当作函数

    构造函数与普通函数的区别在于调用它们的方式不同,只要通过new操作符调用,它就可以作为构造函数.

    // 当作构造函数使用,使用new操作符来创建一个新对象.
    var person = new Person("zhu", 26, "FE");
    person.sayName();
    
    // 作为普通函数调用,属性和方法都被添加到window对象.
    // 在全局作用域中调用一个函数时,this对象总是指向Global对象(在浏览器中就是window对象)
    Person("zhu", 26, "FE");
    window.sayName();
    
    // 使用call()或者apply()在某个特定对象的作用域中调用
    var o = new Object();
    Person.call(o, "zhu", 26, "FE");
    o.sayName();
    

    ps. 构造函数模式定义的构造函数是定义在Global对象中的.

    2.4 构造函数的问题

    每个方法都要在每个实例上重新创建一遍,person1和person2的同名sayName方法不是同一个function的实例.

    ps. ECMAScript的函数是对象,因此每定义一个函数,也就实例化一个对象.即每个Person实例都包含一个不同function实例.

    // 逻辑上的构造函数可以这样定义
    function Person(name, age) {
        this.name = name;
        this.age = age;
        this.sayName = new function() {
            console.log(this.name);
        }
    }
    

    没有必要创建两个完成同样任务的function实例,然而将sayName提到全局虽然解决做同一件事的问题,但是实际上只能被某个对象调用,而且可能需要定义很多全局函数(无封装性).

  • 相关阅读:
    poj2411 状压dp
    棋盘覆盖TYVJ1035(二分图最大匹配)
    poj3417
    无向图边双+缩点
    无向图点双+缩点
    bzoj1123(割点加路径统计)
    【BZOJ1178】会议中心(APIO2009)-贪心+倍增+set
    【BZOJ4650】优秀的拆分(NOI2016)-后缀数组+RMQ+差分
    【BZOJ4569】萌萌哒(SCOI2016)-并查集+倍增
    【BZOJ2208】连通数(JSOI2010)-SCC+DP+bitset
  • 原文地址:https://www.cnblogs.com/LittlePANDA-ZSJ/p/11074523.html
Copyright © 2020-2023  润新知