Object类型是JavaScript中使用最多的一种类型。创建Object实例的方式有多种,接下来一一列举。
1. Object构造函数
var person = new Object();
person.name = "Brittany";
person.age = 23;
person.job = "web front-end engineer";
person.sayName = function() {
console.log(this.name);
};
person.sayName(); //Brittany
2. 对象字面量模式
var person = {
name: "Brittany",
age: 23,
job: "web front-end engineer",
sayName: function() {
console.log(this.name);
}
};
person.sayName();
虽然Object构造函数或对象字面量都可以用来创建单个对象,但这些方式有个明显的缺点:使用同一个接口创建很多对象,会产生大量的重复代码。为解决这个问题,可以使用工厂模式的一种变体。
3. 工厂模式
function createPerson(name, age, job) {
var o = new Object();
o.name = name;
o.age = age;
o.job = job;
o.sayName = function() {
console.log(this.name);
};
return o;
}
var person1 = createPerson("Brittany", 23, "Software Engineer");
var person2 = createPerson("Sam", 26, "Software Engineer");
console.log(typeof person1); //Object
工厂模式虽然解决了创建多个相似对象的问题,但却没有解决对象识别的问题(即怎样知道一个对象的类型)。如代码中只能检测出person1为Object类型。随着JavaScript的发展,又一个新模式出现了。
4. 构造函数模式
function Person(name, age, job) {
this.name = name;
this.age = age;
this.job = job;
this.sayName = function() {
console.log(this.name);
}
}
var person1 = new Person("Brittany", 23, "Web front-end engineer");
var person2 = new Person("Closure", 26, "Manager");
person1.sayName();
person2.sayName();
console.log(person1.sayName == person2.sayName); //false
使用构造函数的主要问题:每个方法都要在每个实例上重新创建一遍。如代码中所示,person1的sayName和person2的sayName不相等。可以将函数定义转移到构造函数外部来解决。
function Person(name, age, job) {
this.name = name;
this.age = age;
this.job = job;
this.sayName = sayName;
}
function sayName() {
console.log(this.name);
}
sayName函数的定义转移到了构造函数外部。而在构造函数内部,我们将sayName属性设置成等于全局的sayName函数。这样一来,由于sayName包含的是一个指向函数的指针,因此person1和person2对象就共享了在全局作用域中定义的同一个sayName()函数。这的确解决了两个函数做同一件事的问题,可是新问题又来了:在全局作用域中定义的函数实际上只能被某个对象调用,这让全局作用域有点名不副实。而更让让人无法接受的是:如果需要定义很多方法,那就要定义很多个全局函数,于是这个自定义的引用类型就无封装性可言。这些问题可通过使用原型模式来解决。
5. 原型模式
function Person() {}
Person.prototype.name = "Brittany";
Person.prototype.age = 23;
Person.prototype.job = "Web front-end engineer";
Person.prototype.getName = function() {
console.log(this.name);
};
var p1 = new Person();
var p2 = new Person();
console.log(p1.name); //Brittany
console.log(p2.name); //Brittany
console.log(p1.getName == p2.getName); //true
实例中创建的属性会覆盖原型中的同名属性,不能修改原型中的属性。
p1.name = "Susan";
console.log(p1.name); //Susan
hasOwnProperty()检测一个属性是否存在于实例中。
console.log(p2.hasOwnProperty("name")); //false
p2.name = "koko";
console.log(p2.hasOwnProperty("name")); //true
delete p2.name;
console.log(p2.hasOwnProperty("name")); //false
isPropertyOf()
console.log(Person.prototype.isPrototypeOf(p1)); //true
console.log(Person.prototype.isPrototypeOf(p2)); //true
getPropertyOf()
console.log(Object.getPrototypeOf(p1) == Person.prototype); //true
console.log(Object.getPrototypeOf(p1)); //Person
JavaScript 对象的创建
原文:http://www.cnblogs.com/sun-mile-rain/p/4041672.html