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

对象创建和继承
对象创建指的是自定义对象构造函数,用于批量创建拥有共同属性方法的对象。例如创建一个人对象构造函数,然后实例化出小明,小红
继承指的是两个引用类型对象间属性和方法的继承,原理是利用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”
 
 
 
原文地址:https://www.cnblogs.com/chuangweili/p/5161025.html