您的位置:首页 > 其它

类(对象)的定义 自定义对象构造函数

2016-01-26 17:11 295 查看
对象创建和继承
对象创建指的是自定义对象构造函数,用于批量创建拥有共同属性方法的对象。例如创建一个人对象构造函数,然后实例化出小明,小红
继承指的是两个引用类型对象间属性和方法的继承,原理是利用prototype,因为实例内部保留了对构造函数prototype的指针,prototype保留对该构造函数的指针。所以如果把构造函数的prototype指向另一个对象类型实例的话,那么也就继承了该实例对构造函数prototype的指针以及它对构造函数的指针。

1、最古老的工厂模式,就是在里面新建对象,然后配置属性,返回这个对象,问题是无法判断对象类型(用不了instanceof):
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;

}
var person1 = createPerson(“Nicholas”, 29, “Software Engineer”);
var person2 = createPerson(“Greg”, 27, “Doctor”);

2、构造函数模式,可以用instanceof来判断了,问题是每个实例都会创建相同的方法,没用公用:
function Person(name, age, job){
this.name = name;
this.age = age;
this.job = job;
this.sayName = function(){
alert(this.name);
};
}
var person1 = new Person(“Nicholas”, 29, “Software Engineer”);
var person2 = new Person(“Greg”, 27, “Doctor”);

当函数被一个 new 调用时,函数的运行方式就改变了, 把 new 看作是一个方法的话,类似下面:
Function.method('new', function () {

var that = Object.create(this.prototype); // Create a new object that inherits from the constructor's prototype.

var other = this.apply(that, arguments); // Invoke the constructor, binding –this- to the new object.

return (typeof other === 'object' && other) || that; // If its return value isn't an object, substitute the new object.

});

忘记 new 的话,this 指向的是 全局变量,要避免这个问题,就加多一层检测(scope-safe):

function Car(sColor) {
if(this instanceof Car ) {

this.color = sColor;
}else {
return new Car(sColor);
}
}
这样做的问题是关闭了可以调用构造函数的上下文:
function Polygon(sides){


if (this instanceof Polygon) {
this.sides = sides;
this.getArea = function(){
return 0;
};
} else {
return new Polygon(sides);
}



}
function Rectangle(width, height){


Polygon.call(this, 2); //这里的调用Polygon返回一个新的Polygon实例,因此this没有被扩张
this.width = width;
this.height = height;
this.getArea = function(){
return this.width * this.height;
};


}
Rectangle.prototype = new Polygon(); //如果没有这句就会得不到2,而是undefined
var rect = new Rectangle(5, 10);
alert(rect.sides); //2

3、prototype 模式,问题是所有属性都公用了,而且还不能传递初始化的值:
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

4、混合构造函数模式和prototype模式,取各自优点:
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);
}
};

5、Dynamic Prototype Pattern:
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);
};
}
}
var friend = new Person(“Nicholas”, 29, “Software Engineer”);

6、Parasitic Constructor Pattern:
function SpecialArray(){
var values = new Array();
values.push.apply(values, arguments);
values.toPipedString = function(){
return this.join(“|”);
};

return values;
}
var colors = new SpecialArray(“red”, “blue”, “green”);
alert(colors.toPipedString()); //”red|blue|green”

7、Durable Constructor Pattern,这种模式实例和构造函数原型没关系,无法使用instanceof:
function Person(name, age, job){
//create the object to return
var o = new Object();
//optional: define private variables/functions here
//attach methods
o.sayName = function(){
alert(name);
};
//return the object
return o;
}
var friend = Person(“Nicholas”, 29, “Software Engineer”);
friend.sayName(); //”Nicholas”
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: