本文是金旭亮老师网易云课堂的课程笔记,记录下来,以供备忘。
我们可以编写一个函数,此函数的功能就是创建对象,可将其称为“对象工厂方法”。
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, '医生');
//定义对象“构造”函数 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添加的属性, //成为了window对象的属性与方法。 console.info(window.name);//张三 console.info(window.age); //29 console.info(window.job); //软件工程师
对象构造函数长得这个样:
1 function Person (name) { this.name = name; this.say = function () { return "I am " + this.name; }; }
实际上是这样(示意):
1 function Person (name) { // var this = {}; this.name = name; this.say = function () { return "I am " + this.name; }; // return this; }
a).使用对象工厂函数创建对象,每个对象的constructor属性引用Object()
1 var person = createPerson('张三', 29, '软件工程师'); //使用工厂方法创建对象,其constructor属性引用Object()函数 console.info(person1.constructor === Object); //true
b).使用对象构造函数创建对象,每个对象的constructor属性引用这个构造函数
1 var p = new Person('张三', 29, '软件工程师'); //使用对象构造函数创建对象, //每个对象的constructor属性,引用这个构造函数 console.info(p.constructor === Person); //true
可以使用arguments.callee解决这个问题
1 //了解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
1 //避免忘记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