创建对象的两种方法
1. new操作符
var o = new Object();
var o = new Object();
o.name = 'wzd';
o.job = function () {
alert(this.name);
}
o.job();
2. 对象字面量
var o = {};
var o = {
name: 'wzd',
job: function () {
alert(this.name);
}
}
o.job();
上述两种方法的缺点是使用一个接口创建很多对象,会产生大量重复代码
解决方法:
1.工厂模式
function Person (name, age,job) {
var o = new Object();
o.name = name;
o.age = age;
o.job = job;
o.sayName = function () {
alert(this.name);
}
return o;
}
var person1 = Person('wzd',14,'doctor');
person1.sayName();
var person2 = Person('hja',14,'doctor');
person2.sayName();
工厂模式虽然解决了创建多个相似对象的问题,但却没有解决对象识别的问题(即怎么知道一个对象的类型);
2.构造函数模式
function Person (name, age, job) {
this.name = name;
this.age = age;
this.job = job;
this.sayName = function () {
alert(this.name);
}
}
var person1 = new Person('wzd',14,'doctor');
var person2 = new Person('hja',14,'doctor');
构造模式虽然好用,但也并非没有缺点.使用构造函数的主要问题,就是每个方法都要在每个实例上重新创建一遍.
说明白些,以这种方式创建函数,会导致不同的作用域链和标识符解析,但创建Function新实例的机制仍然是相同的.
以下代码可以证明这一点:
alert(person1.sayName == person2.sayName); //false
因此可以通过把函数定义转移到构造函数外部来解决这个问题:
function Person (name, age, job) {
this.name = name;
this.age = age;
this.job = job;
this.sayName = sayName;
}
function sayName () {
alert(this.name);
}
var person1 = new Person('wzd',14,'doctor');
var person2 = new Person('hja',14,'doctor');
alert(person1.sayName == person2.sayName); //true
但是很明显,这种方法让对象调用全局函数,如果定义了很多个全局函数,那就毫无封装性可言.
3.原型模式
function Person () {};
Person.prototype.name = 'wzd';
Person.prototype.age = 14;
Person.prototype.job = 'doctor';
Person.prototype.sayName = function () {
alert(this.name);
}
var person1 = new Person();
var person2 = new Person();
alert(person1.sayName == person2.sayName);
4. 组合使用构造函数和原型模式
function Person (name, age, job) {
this.name = name;
this.age = age;
this.job = job;
}
Person.prototype = {
constructor: Person,
sayName: function () {
alert(this.name);
}
}
var person1 = new Person('wzd',14,'doctor');
var person2 = new Person('hja',14,'doctor');
alert(person1.sayName == person2.sayName);