看了JavaScript中面向对象的一章,里面讲到关于对象创建的几种模式,在这里做一下总结。
工厂模式
直接上代码
function createPerson(name,age,job){
var o = new Object();
o.name = name;
o.age = age;
o.job = job;
o.sayName = function(){
alert(this.name);
}
return o;
}
工厂模式虽解决了创建多个相似对象的问题,但却没有解决对象识别的问题(怎么知道一个对象的类型),随着JavaScript的发展,又一个模式出现了。
构造函数模式
function Person(name,age,job){
this.name = name;
this.age = age;
this.job = job;
this.sayName = function(){
alert(this.name);
}
}
相比与工厂模式,不同之处在于:
- 没有显示地创建对象
- 直接将属性和方法赋给了this对象
- 没有return语句
注意:构造函数始终以一个大写字母开头,而非构造函数则应该以一个小写字母开头。
// 当作构造函数使用(通过new操作符来调用)
var person = new Person('jh',19,'Software Engineer');
person.sayName(); //'jh'
构造函数的问题:
每个方法都要在每个实例上重新创建一遍。以这种方式创建函数,会导致不同的作用域链和标识符解析,因此,不同实例上的同名函数是不相等的,以下代码可说明问题:
alert(person1.sayName == person2.sayName); //false
原型模式
function Person(){
}
Person.prototype.name = "Nicholas";
Person.prototype.age = 29;
Person.prototype.job = "Software Engineer";
Person.prototype.sayName = function(){
alert(this.name);
}
var person1 = new Person();
person1.sayName(); //"Nicholas"
var person2 = new Person();
person2.sayName(); //"Nicholas"
alert(person1.sayName == person2.sayName); //true
Tips: 使用hasOwnProperty()方法可检测一个属性是否存在于 实例 中。(原型属性不行)
要取得对象上所有可枚举的实例属性,可用ECMAScript5的Object.keys()方法,这个方法接收一个对象作为参数,返回一个包含所有可枚举属性的字符串数组
function Person(){
}
Person.prototype.name = "Nicholas";
Person.prototype.age = 29;
Person.prototype.job = "Software Engineer";
Person.prototype.sayName = function(){
alert(this.name);
}
var keys = Object.keys(Person.prototype);
alert(keys); //"name,age,job,sayName"
var p1 = new Person();
p1.name = "Rob";
p1.age = 31;
var p1keys = Object.keys(p1);
alert(p1keys); //"name,age"
原型对象的问题:
原型中的所有属性被实例共享,可是实例一般都是要有属于自己的全部属性的。
组合使用构造函数模式和原型模式
function Person(name,age,job){
this.name = name;
this.age = age;
this.job = job;
this.friends = ['Shelby','Court'];
}
Person.prototype = {
constructor: Person,
sayName: function() {
alert(this.name);
}
}
在这个例子中,实例属性都是在构造函数中定义的,而所有实例共享的属性constructor和方法则是在原型中定义的。修改一个实例中的friends属性,并不会影响另一个实例中的friends。
动态原型方法
function Person(name,age,job){
//属性
this.name = name;
this.age = age;
this.job = job;
//方法
if(typeof this.sayName != function){
Person.prototype.sayName = function(){
alert(this.name);
};
}
}
注意,这里只在sayName()方法不存在的情况下,才会将它添加到原型中。
以上是几种常用的构造函数模式,应理解其中的精髓和每种模式的优点和缺点,在合适的情境下使用。
注:本文内容来自互联网,旨在为开发者提供分享、交流的平台。如有涉及文章版权等事宜,请你联系站长进行处理。