您所在的位置:小祥子 » 编程 » JavaScript » 正文

Javascript我学之六对象工厂函数与构造函数

时间:2015-07-27 编辑:秋官 来源:CnBlogs

 本文是金旭亮老师网易云课堂的课程笔记,记录下来,以供备忘。

概述

  • 使用对象字面量,或者向空对象中动态地添加新成员,是最简单易用的对象创建方法。
  • 然而,除了这两种常用的对象创建方式,JavaScript还提供了其他方法创建对象。

1).使用工厂函数创建对象

我们可以编写一个函数,此函数的功能就是创建对象,可将其称为“对象工厂方法”。

    //工厂函数
         function createPerson(name, age, job) {
             var o = new Object();
             o.name = name;
             o.age = age;
             o.job = job;
             o.sayName = function () {
                 console.info(this.name);
             };
             return o;
         }
         //使用工厂函数创建对象
         var person1 = createPerson('张三', 29, '软件工程师');
         var person2 = createPerson('李四', 40, '医生');

2).定义对象构造函数

  a).对象构造函数首字母大写   b).内部使用this关键字给对象添加成员   c).使用new关键字调用对象构造函数
       //定义对象“构造”函数
        function Person(name, age, job) {
            this.name = name;
            this.age = age;
            this.job = job;
            this.sayName = function () {
                console.info(this.name);
            };
        }
        //使用new调用对象构造函数创建对象
        var p1 = new Person('张三', 29, '软件工程师');
        var p2 = new Person('李四', 40, '医生');

以普通方式调用的“构造函数”

构造函数其实也是一个函数,不同之处在于调用它时必须要加一个“new”关键字,如果不加这个关键字,则对它的调用被认为是普通函数调用。

        //作为普通函数调用的构造函数,通过this添加的属性,
         //成为了window对象的属性与方法。
         console.info(window.name);//张三
         console.info(window.age); //29
         console.info(window.job); //软件工程师

对象构造函数长得这个样:

 function Person (name) {
      this.name = name;
      this.say = function () {
          return "I am " + this.name;
      };
 }

实际上是这样(示意):

 function Person (name) {
       // var this = {};
       this.name = name;
       this.say = function () {
            return "I am " + this.name;
      };
       // return this;
 }

构造函数完成的工作

1. 创建一个新的对象 2. 让构造函数的this引用这一新创建的对象 3. 执行构造函数中的代码,这些代码通常完成向新对象添加属性的工作 4. 向外界返回新创建的对象引用。  

对象构造函数与对象工厂方法的区别


1. 对象构造函数中没有显式的对象创建代码 2. 新对象应具备的属性与方法是通过this引用添加的. 3. 对象构造函数中没有return语句   通常会把对象构造函数的首字母设置为大写的,以区别于普通函数。

对象的constructor属性

a).使用对象工厂函数创建对象,每个对象的constructor属性引用Object()

       var person = createPerson('张三', 29, '软件工程师');
 
      //使用工厂方法创建对象,其constructor属性引用Object()函数
         console.info(person1.constructor === Object);  //true

b).使用对象构造函数创建对象,每个对象的constructor属性引用这个构造函数

 var p = new Person('张三', 29, '软件工程师');
 //使用对象构造函数创建对象,
 //每个对象的constructor属性,引用这个构造函数
 console.info(p.constructor === Person); //true

如何避免“忘记”new?

可以使用arguments.callee解决这个问题

         //了解arguments.callee的作用
         function TestArgumentsCallee() {
             console.info(this);
             console.info(this instanceof TestArgumentsCallee);
             console.info(this instanceof arguments.callee);
         };
         TestArgumentsCallee(); //window
                                             //false
                                             //false
         new TestArgumentsCallee();  //TestArgumentsCallee
                                                      //true
                                                      //true

于是,可以直接用arguments.callee

         //避免忘记new
         function MyObject(value) {
             if (!(this instanceof arguments.callee)) {
                 //如果调用者忘记加上new了,就加上new再调用一次
                 return new MyObject(value);
             }
             this.prop = value;
         }
         //测试
         var obj1 = new MyObject(100);
         console.info(obj1.prop);//100
         var obj2 = MyObject(200);
         console.info(obj2.prop); //200
关键词:对象 函数