工厂模式:
function createPerson(name, age) { var o = new Object(); //创建一个要返回的对象 o.name = name; //给该对象设置域 o.age = age; o.sayName = function() { alert(this.name); } return o ; //返回该对象 } var a = createPerson("hx", 20, "wan"); a.sayName();
构造函数模式:
function Person(name, age) {this.name = name; this.age = age; this.sayHello = function() { alert(this.name + "hello"); } } var p = new Person("hx", 20);
对比:
1.获取对象方式:构造函数模式调用时使用 new 操作符对象,
工厂模式获取对象使用接收函数返回值.
2.类型检测: 使用构造函数生成的对象可以使用 p instanceof Person检测
工厂模式只能 p instanceof Object
3.调用者 :构造函数模式的调用者时将要创建的对象,所以
function Person(name, age) { alert (this instanceof Person); alert(typeof this) this.name = name; this.age = age; this.sayHello = function() { alert(this.name + "hello"); } } var p = new Person("hx", 20);
this instanceof Person为true,
而在工厂模式中,工厂方法本身就是一个方法,只不过返回值是一个有特定属性的对象,所以其调用者在本例中为Window对象.
稳妥构造函数模式:
function Person(name, age) { var o = new Object(); this.name = name; this.age = age; o.sayName = function(){ alert(name); } return o; } var p = Person("hx", 20); p.sayName();
我们使用for ... in遍历对象, 在工厂模式和构造函数模式中都可以遍历到name,age属性,和sayName函数对象,但是在这个稳妥构造函数模式中,只能访问到sayName方法,
我们在定义name和age属性时使用的是this.name,this.age,这个this指代的是window对象
function Person(name, age) { var o = new Object(); this.name = name; this.age = age; o.sayName = function(){ alert(name); } return o; } var p = Person("hx", 20); var a; for (a in window){ console.log(a + " : " + window[a]) }
在控制台的信息中我们可以看到我们定义的 name:hx,age:20,太长了,不粘贴了.
我们可以通过alert(name)看到定义的属性.
所以这种方式创建的对象,感觉就不应该是一个对象,而是多个对象的引用,其name好像引用的是window.name,但是我们修改代码
function Person(name, age) { var o = new Object(); this.name = name; this.age = age; o.sayName = function(){ alert(name); } return o; } var p = Person("hx", 20); window.name = "new"; p.sayName(); console.log(window.name);
可以看到对象p中的sayName依旧是hx,但是window.name为new,为什么呢??
不知道