javascript 创建对象 模式总结

 内容总结自《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;                                    
 }
var person1 = createPerson(“Nicholas”, 29, “Software Engineer”); //函数调用
var person2 = createPerson(“Greg”, 27, “Doctor”);
包含三个属性一个方法的对象,返回的是同一实例     对象无法识别,即返回的是同一对象  
构造函数模式
function Person(name, age, job){
    this.name = name;
    this.age = age;
    this.job = job;
    this.sayName = function(){ 
       alert(this.name);
    };
    //每定义一个函数,就是实例化了一个对象!
    //逻辑上等同于: this.sayName = new function(){};
}
var person1 = new Person(“Nicholas”, 29, “Software Engineer”); 
var person2 = new Person(“Greg”, 27, “Doctor”);
person1、person2分别保存Person不同实例 constructor:指向Person;是共享的   每个方法都要在每个实例上重新创建一遍 1.构造函数适中以大写字母开头;
2.构造函数本身也是函数,只不过可以用来创建对象;
3.必须使用new否则跟普通函数没有区别;
4.不使用new,this对象会指向window
构造函数模式2
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(“Nicholas”, 29, “Software Engineer”);
var person2 = new Person(“Greg”, 27, “Doctor”);
同上 同上   全局作用域中的函数实际上只被某个对象调用了,杀鸡焉用宰牛刀?! 方法sayName()从构造函数中拿出来了。
原型模式
function Person(){
}
Person.prototype.name = “Nicholas”;
Person.prototype.age = 29;
Person.prototype.job = “Software Engineer”;
Person.prototype.sayName = function(){
    alert(this.name);
};
/****更简单的原型语法,此时上下文顺序不可变**********
此时constructor不指向Person,默认指向Object构造函数
Person.prototype = {
    constructor : Person, //须手动指向constructor
    name : "Nicholas",
    age : 29,
    job : “Software Engineer”,
    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
新对象的属性和方法由所有实例共享 prototype:原型指针,指向对象(通过调用构造函数而创建的那个对象实例的原型对象,即Person Prototype) 关系检测方法:isPrototypeOf();
获得值: getPrototypeOf();
检测属性属于实例: hasOwnProperty();
检测属性存在: in;
得到全部实例属性: getOwnPropertyNames();
包含引用类型值的属性 共享,如String、Array、Object等 1.创建的每个函数都有一个prototype属性;
2.[[prototype]]指向Person.prototype;
3.不能通过对象实例重写原型中的值
组合使用构造函数模式和原型模式
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);}
};
var person1 = new Person(“Nicholas”, 29, “Software Engineer”);
var person2 = new Person(“Greg”, 27, “Doctor”);
person1.friends.push(“Van”);
alert(person1.friends); //”Shelby,Court,Van”
alert(person2.friends); //”Shelby,Court”
alert(person1.friends === person2.friends); //false
alert(person1.sayName === person2.sayName); //true
        1.构造函数模式用于定义实例属性,原型模式用于定义方法和共享的属性。
2.目前在ECMAScript中使用最广泛、认同度最高的;用来定义引用类型的一种默认模式。
动态原型模式
function Person(name, age, job){
    //properties
    this.name = name;
    this.age = age;
    this.job = job;
   //methods
    if (typeof this.sayName != “function”){
        Person.prototype.sayName = function(){
            alert(this.name);
        };
    }
}
var friend = new Person(“Nicholas”, 29, “Software Engineer”);
friend.sayName();
        所有信息都封装在构造函数中,通过在构造函数中初始化原型;即 通过检查某个应该存在的方法是否有效来决定是否需要初始化原型。
寄生构造函数模式
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 friend = new Person(“Nicholas”, 29, “Software Engineer”); //调用与工厂模式有区别
friend.sayName(); //”Nicholas”
        1.除用new以外,其他跟工厂模式一样;
2.构造函数返回的对象与在构造函数外部创建的对象没有不同。所以,不能依赖instanceof操作符确定对象类型。
3.尽量不使用这种方式
稳妥构造函数模式
function Person(name, age, job){
    //创建要返回的对象
    var o = new Object();
    //可以在这里定义私有变量和函数

    //添加方法
    o.sayName = function(){ alert(name); };
    //返回对象
    return o;
}
var friend = Person("Nidcholas", 29, "Software Engineer");
friend.sayName(); //"Nicholas"
1.除非使用 sayName()方法,没有其他方法访问name的值
2.不可能有别的方法访问传入到构造函数中的原始数据
稳妥对象: 没有公共属性、且其方法不引用this的对象     1.适用于安全环境(禁止this和new);
2.遵循与计生构造函数类似的模式,但不用this和new;
3.安全执行环境举例:Adsafe、Caja;
4.同上第2条。
  附注:复制代码做测试时,注意有些双引号为中文模式,需修改为英文模式。          
原文地址:https://www.cnblogs.com/zldream1106/p/3090340.html