JavaScript中工厂模式和构造函数模式

========设计模式===========
第一个设计模式:工厂模式。
一般我们是通过Object和工厂模式的方式创建对象。
现实中这种方式使用的也是最多的。但是做事要追求
高大上。这是一种信仰。学会在实际中尽量使用设计模式。
比如创建一个Person实例。
var person = new Object();
person.name = "希斯克利夫";
person.theme = "呼啸山庄";
console.log(person instanceof Object);
结果显示true;
这说明,生成的对象是一个Object对象。

这是第一种创建方式,也就是通过Object的方法动态地生成一个对象。
另一种方式就是使用普通函数的方式。
function personCreate(name, theme) {
var o = new Object();
o.name = name;
o.theme = theme;
o.sayHello = function() {
console.log("Hello World!");
}
return o;
}

第二个设计模式:构造函数模式。
还有一种就是使用构造函数的方式
function Person(name, theme) {
this.name = name;
this.theme = theme;
this.sayHello = function() {
console.log(name + " : " + theme);
}
}
console.log(person instanceof Object);
console.log(person instanceof Person);

做一个验证:验证的目的就是这些方式创建的对象的类型是什么?
其实很明显,第一种方式和第二种方式生成的对象的类型一定是object类型,
因为对象的生成都是直接或者间接依赖于Object对象的方式。

但是第三种似乎有些不同,它的创建对象的方式采用new的方法。不仅仅是Object类型
而且是Person类型。接触过Java的人一看就明白,Person类继承自Object类,所以才会
出现person不仅仅是Object类型而且是Person类型。

也就是说采用构造函数的方式比采用简单工厂的模式在生成对象的类型上多出一种特性。
那么这唯一的一点优点到底有怎样的威力呢?目前还不知道。

至于构造函数模式还存在一个问题:
var person1 = new Person("希斯克利夫", "呼啸山庄");
var person2 = new Person("拉斯柯尔尼科夫", "罪与罚");
person1.sayHello();
person2.sayHello();
那就是sayHello方法的问题。
第一点需要说明那就是,sayHello方法实际就是一个对象。因为在JavaScript中函数就是对象。
这里实例化了两个对象person1,person2。同时这两个对象都包含sayHello对象,从内存的角度
来看,这是一种浪费。区别仅仅是在函数中使用的属性不同,仅此而已。
因此演化出了另一种过度模式,也就是将方法提取出来,有对象域,离心到全局域。
同时在构造函数域中保存公共方法的引用。
function sayHello() {
console.log(this.name + " : " + this.theme);
}

function Person(name, theme) {
this.name = name;
this.theme = theme;
this.sayHello = sayHello;
}
这里存在一个作用域的传递问题。
当person1对象调用sayHello方法时在方法内部调用的属性是person1的属性
当person2对象调用sayHello方法时在方法内部调用的属性是person2的属性
问题是sayHello方法方法是公用的,那么内部的属性就是共享数据,
难道就不怕造成污染吗?当然怕!解决的方法不是锁机制。而是修改作用域。
神来之笔!
怎么修改作用域?下回分解。

猜你喜欢

转载自blog.csdn.net/qq_23143555/article/details/80701388