一、工厂方式
缺点:每次调用 函数 时,都要创建新的 getInfo()函数,每个对象都有着自己的 getInfo() 版本
<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta charset="utf-8" />
<title>创建对象|工厂模式</title>
<script>
function newPerson(name, age, gender) {
var Person = new Object;
Person.name = name;
Person.age = age;
Person.gender = gender;
Person.getInfo = function () {
alert("姓名:" + this.name + "\n\n年龄:" + this.age + "\n\n性别:" + this.gender);
}
return Person;
}
var p = newPerson("xxx", 16, "女");
p.getInfo();
</script>
</head>
<body>
</body>
</html>
修改:
function getInfo(){
alert("姓名:" + this.name + "\n\n年龄:" + this.age + "\n\n性别:" + this.gender);
}
function newPerson(name, age, gender) {
var Person = new Object;
Person.name = name;
Person.age = age;
Person.gender = gender;
Person.getInfo = getInfo;
return Person;
}
以上修改解决了重复创建函数的问题,但是该函数看起来不像是对象的方法。
二、构造函数方式
构造函数方式与工厂模式相比,内部不用构造对象,使用this关键字。在构造对象时使用new运算符。但是,也会出现工厂模式中出现的问题,同时也可以像工厂模式那样解决。
function Person(name, age, gender) {
this.name = name;
this.age = age;
this.gender = gender;
this.getInfo = function () {
alert("姓名:" + this.name + "\n\n年龄:" + this.age + "\n\n性别:" + this.gender);
}
}
var p = new Person("xxx", 16, "女");
p.getInfo();
三、原型方式
缺点:
- 不能通过构造函数传递参数进行初始化
- 类似以下类中的drivers是指向Array的指针,当改变p2中drivers的值时,p1中的drivers也随之改变
function Person() {
}
Person.prototype.name = "xxx";
Person.prototype.age = 16;
Person.prototype.gender = "女";
Person.prototype.drivers = new Array("a", "b");
Person.prototype.getInfo = function(){
alert("姓名:" + this.name + "\n\n年龄:" + this.age + "\n\n性别:" + this.gender);
}
var p1 = new Person();
alert(p1.drivers);
var p2 = new Person();
alert(p2.drivers);
p2.drivers.push("sss");
alert(p1.drivers);
alert(p2.drivers);
四、混合构造函数与原型方式
function Person(name, age, gender) {
this.name = name;
this.age = age;
this.gender = gender;
this.drivers = new Array("a", "b");
}
Person.prototype.getInfo = function () {
alert("姓名:" + this.name + "\n\n年龄:" + this.age + "\n\n性别:" + this.gender);
}
var p1 = new Person("npc1", 18, "男");
var p2 = new Person("npc2", 18, "女");
alert(p1.drivers);
alert(p2.drivers);
p1.drivers.push("c");
alert(p1.drivers);
alert(p2.drivers);
五、动态原型方法
function Person(name,age,gender) {
this.name = name;
this.age = age;
this.gender = gender;
if (typeof Person._initialized == "undefined") {
Person.prototype.getInfo = function () {
alert("姓名:" + this.name + "\n\n年龄:" + this.age + "\n\n性别:" + this.gender);
}
Person._initialized = true;
}
}
var p1 = new Person("xxx", 17, "abc");
p1.getInfo();
一般采取后面两种方式定义类或对象