Javascript我学之六对象工厂函数与构造函数
本文是金旭亮老师网易云课堂的课程笔记,记录下来,以供备忘。
概述
- 使用对象字面量,或者向空对象中动态地添加新成员,是最简单易用的对象创建方法。
- 然而,除了这两种常用的对象创建方式,JavaScript还提供了其他方法创建对象。
1).使用工厂函数创建对象
我们可以编写一个函数,此函数的功能就是创建对象,可将其称为“对象工厂方法”。
1 //工厂函数 2 function createPerson(name, age, job) { 3 var o = new Object(); 4 o.name = name; 5 o.age = age; 6 o.job = job; 7 o.sayName = function () { 8 console.info(this.name); 9 }; 10 return o; 11 } 12 //使用工厂函数创建对象 13 var person1 = createPerson('张三', 29, '软件工程师'); 14 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”关键字,如果不加这个关键字,则对它的调用被认为是普通函数调用。
1 //作为普通函数调用的构造函数,通过this添加的属性, 2 //成为了window对象的属性与方法。 3 console.info(window.name);//张三 4 console.info(window.age); //29 5 console.info(window.job); //软件工程师
对象构造函数长得这个样:
1 function Person (name) { 2 this.name = name; 3 this.say = function () { 4 return "I am " + this.name; 5 }; 6 }
实际上是这样(示意):
1 function Person (name) { 2 // var this = {}; 3 this.name = name; 4 this.say = function () { 5 return "I am " + this.name; 6 }; 7 // return this; 8 }
构造函数完成的工作
1. 创建一个新的对象
2. 让构造函数的this引用这一新创建的对象
3. 执行构造函数中的代码,这些代码通常完成向新对象添加属性的工作
4. 向外界返回新创建的对象引用。
对象构造函数与对象工厂方法的区别
1. 对象构造函数中没有显式的对象创建代码
2. 新对象应具备的属性与方法是通过this引用添加的.
3. 对象构造函数中没有return语句
通常会把对象构造函数的首字母设置为大写的,以区别于普通函数。
对象的constructor属性
a).使用对象工厂函数创建对象,每个对象的constructor属性引用Object()
1 var person = createPerson('张三', 29, '软件工程师'); 2 3 //使用工厂方法创建对象,其constructor属性引用Object()函数 4 console.info(person1.constructor === Object); //true
b).使用对象构造函数创建对象,每个对象的constructor属性引用这个构造函数
1 var p = new Person('张三', 29, '软件工程师'); 2 //使用对象构造函数创建对象, 3 //每个对象的constructor属性,引用这个构造函数 4 console.info(p.constructor === Person); //true
如何避免“忘记”new?
可以使用arguments.callee解决这个问题
1 //了解arguments.callee的作用 2 function TestArgumentsCallee() { 3 console.info(this); 4 console.info(this instanceof TestArgumentsCallee); 5 console.info(this instanceof arguments.callee); 6 }; 7 TestArgumentsCallee(); //window 8 //false 9 //false 10 new TestArgumentsCallee(); //TestArgumentsCallee 11 //true 12 //true
于是,可以直接用arguments.callee
1 //避免忘记new 2 function MyObject(value) { 3 if (!(this instanceof arguments.callee)) { 4 //如果调用者忘记加上new了,就加上new再调用一次 5 return new MyObject(value); 6 } 7 this.prop = value; 8 } 9 //测试 10 var obj1 = new MyObject(100); 11 console.info(obj1.prop);//100 12 var obj2 = MyObject(200); 13 console.info(obj2.prop); //200