javascript 中九种建立对象的方式

javascript 中对于对象的描述:javascript

            ECMA-262 把对象的定义为:“无序属性的集合,其属性能够包含基本值,对象或者函数。”严格来说,这就至关于说对象是一组没有特定顺序的值。对象的每一个属性或方法都有一个名字,而每一个名字都映射到一个值。正是由于这样,咱们能够把 javascript 中的对象想象成散列表:无非就是一组名值对,其中值能够是数据或函数。
java


javascript 中九种建立对象的方式:ide

            一、原生 Object 构造函数函数

            二、对象字面量表示法this

            三、工厂模式spa

            四、构造函数模式prototype

            五、原型模式指针

            六、组合使用构造函数模式和原型模式orm

            七、动态原型模式对象

            八、寄生构造函数模式

            九、稳妥构造函数模式

一、原生 Object 构造函数

具体示例:
// 建立对象
var person = new Object();
// 为对象添加属性
person.name = "luochen";
person.age = 22;
person.job = "student";
// 为对象添加方法
person.sayJob = function(){
           alert(this.job);
};
PS:上面的例子建立了一个名为 person 的对象,并为它添加了三个属性和一个方法。

二、对象字面量表示法

具体示例:
// 建立对象
var person = {
           name: "luochen",
           age: 22,
           job: "student",
           sayJob: function(){
                   alert(this.job);
           }
};
PS:虽然 Object 构造函数或对象字面量均可以用来建立单个对象,但这些方式有个明显的缺点:使用同一个接口建立多个对象,会产生大量的重复代码。

三、工厂模式

具体示例:
// 自定义建立对象的函数
function createPerson(name,age,job){
           var o = new Object();
           o.name = name;
           o.age = age;
           o.job = job;
           o.sayJob = function(){
                   alert(this.job);          
           };
           return o;
}
var  person1 = createPerson("luochen",22,"student");
PS:工厂模式的原理就是自定义一个函数,用函数来封装以特定接口建立对象的细节。这个函数能够接收一些必要参数用来初始化对象,函数内部最后将这个新对象返出,在函数外部将这个调用这个函数的结果赋值给一个新变量。工厂模式虽然解决了建立多个类似对象的问题,但却没有解决对象识别的问题。

四、构造函数模式

具体示例:
// 建立自定义构造函数,从而定义自定义对象类型的属性和方法
function Person(name,age,job){
           this.name = name;
           this.age = age;
           this.job = job;
           this.sayJob = function(){
                   alert(this.job);
           };                                                                        
}
var person1 = new Person("luochen",22,"student");
PS:构造函数模式和工厂模式的区别:
           一、没有显示地建立对象
           二、直接将属性和方法赋值给了 this 对象
           三、没有 return 语句
       以 new 操做符调用构造函数建立对象实际上会经历如下4个步骤:
           一、建立一个新对象
           二、将构造函数的做用域赋给新对象(所以 this 就指向了这个新对象)
           三、执行构造函数中的代码(为这个新对象添加属性)
           四、返回新对象
建立自定义的构造函数意味着未来能够将它的实例标识为一种特定的类型;而这正是构造函数模式赛过工厂模式的地方。构造函数有个明显的缺点就是每一个方法都要在每一个实例上从新建立一遍,即不一样实例上的同名函数是不相等的。

五、原型模式

具体示例:
// 不在构造函数中定义对象实例的信息,而是能够将这些信息直接添加到原型对象中
function Person(){
}
Person.prototype.name = "luochen";
Person.prototype.age = 22;
Person.prototype.job = "student";
Person.prototype.sayJob = function(){
           alert(this.job);
};
var person1 = new Person();
person1.sayJob();
PS:咱们建立的每一个函数都有一个 prototype 的原型属性,这个属性是一个指针,指向一个对象,而这个对象的用途是包含能够由特定类型的全部实例共享的属性和方法,即 prototype 属性指向的那个对象是全部实例的原型对象。原型模式与构造函数模式最大的不一样之处在于:由原型模式建立的对象共享全部的属性和方法(即便用同一组属性和同一个函数)。要格外记住的是:经过原型模式建立的对象实例都不包含属性和方法,但咱们能够调用 person1.sayJob() 这是为啥呢???其实这是经过查找对象属性的过程来实现的。每当代码读取某个对象的某个属性或方法时,都会执行一次搜索,目标是具备给定名字的属性。搜索首先从对象实例自己开始。若是在实例中找到了具备给定名字的属性,则返回该属性的值;若是没有找到,则会继续搜索指针(实例的内部属性 `Prototype`)指向的原型对象,在原型对象中查找具备给定名字的属性。若是在原型对象中找到了这个属性,则返回该属性的值。

// 原型模式更常见的作法是用一个包含全部属性和方法的对象字面量来重写整个原型对象
function Person(){
}
Person.prototype = {
           // 用对象字面量来重写整个原型对象,constructor 属性也就变成了新对象的 constructor 属性(指向 Object 构造函数),再也不指向 Person 函数
           constructor: Person,
           name: "luochen",
           age: 22,
           job: "student",
           sayJob: function(){
                   alert(this.job);
           }
};
var person1 = new Person();
PS:原型模式省略了给构造函数传递参数这一环节,结果全部的实例在默认状况下都将取得相同的属性值,而且当原型对象上有一个引用类型值的属性时,在一个对象实例上对其值的修改,结果会在全部实例中反映出来。

六、组合使用构造函数模式和原型模式

具体示例:
// 构造函数模式用于定义实例属性,而原型模式用于定义方法和共享的属性
function Person(name,age,job){
           this.name = name;      
           this.age = age;
           this.job = job;
           this.friends = ["tom","jerry"];
}
Person.prototype = {
           constructor: Person,
           sayJob: function(){
                   alert(this.job);
           }
};
var person1 = new Person("luochen",22,"student");
var person2 = new Person("shelby",30,"enginner");

person1.friends.push("van");
alert(person1.friends);  // "tom,jerry,van"
alert(person2.friends);  // "tom,jerry"
alert(person1.friends == person2.friends);   // false
alert(person1.sayJob == person2.sayJob);   // true
PS:经过组合使用构造函数模式和原型模式建立的对象实例都会有本身的一份实例属性的副本,但同时又共享着对方法的引用,最大限度地节省了内存。这种模式是目前使用最普遍,认同度最高的一种建立自定义类型的方法。能够说是用来定义引用类型的一种默认模式。

七、动态原型模式

具体示例:
// 把全部信息都封装在构造函数中,在构造函数中经过检查原型初始化以后应该存在的任何属性和方法是否存在,来决定是否须要初始化原型
function Person(name,age,job){
           this.name = name;
           this.age = age;
           this.job = job;
           
           // 判断是否初始化原型
           if(typeof this.sayJob != "function"){
                       Person.prototype.sayJob = function(){
                               alert(this.job);
                       };
           }
}
var person = new Person("luochen",22,"student");
person.sayJob();
PS:对于采用这种模式建立的对象,还可使用 instanceof 操做符肯定它的类型。使用动态原型模式时,不能使用对象字面量重写原型,若是在已经建立了实例的状况下重写原型,那么就会切断现有实例与新原型之间的联系。

八、寄生构造函数模式

具体示例:
// 这种模式的基本思想是建立一个函数,该函数的做用仅仅是封装建立对象的代码,而后在返回新建立的对象
function Person(name,age,job){
           var o = new Object();
           o.name = name;
           o.age = age;
           o.job = job;
           o.sayJob = function(){
                   alert(this.job);
           };
           return o;
}
var person = new Person("luochen",22,"student");
person.sayJob();
PS:这种模式除了使用 new 操做符并把使用的包装函数叫作构造函数以外,跟工厂模式实际上是如出一辙的。构造函数在不返回值的状况下,默认会返回新对象实例。而经过在构造函数的末尾添加一个 return 语句,就能够重写调用构造函数时返回的值。这种模式的缺点是不能经过 instanceof 操做符来肯定对象的类型,由于返回的对象与构造函数或者与构造函数的原型属性之间没有关系。

九、稳妥构造函数模式

具体示例:// 稳妥构造函数遵循与寄生构造函数相似的模式,但有两点不一样:一是新建立对象的实例方法不引用 this;二是不使用 new 操做符调用构造函数function Person(name,age,job){            var o = new Object();            o.name = name;            o.age = age;            o.job = job;            o.sayJob = function(){                    alert(name);            };            return o;}var person = Person("luochen",22,"student");person.sayJob();PS:变量 person 中保存的是一个稳妥对象(指的是没有公共属性,并且其方法也不引用 this 的对象),而除了调用 sayJob() 方法外,没有别的方式能够访问其数据成员。与寄生构造函数模式类似,使用稳妥构造函数模式建立的对象与构造函数之间也没有什么关系,所以 instanceof 操做符对这种对象也没有意义。
相关文章
相关标签/搜索