Javascript建立对象的几种方式?

javascript 中常见的建立对象的几种方式:

 1. 使用Object构造函数建立;

使用Object构造函数来建立一个对象,下面代码建立了一个person对象,并用两种方式打印出了Name的属性值。

var person = new Object();
person.name="kevin";
person.age=31;
alert(person.name);
alert(person["name"])

2. 使用对象字面量建立一个对象;

var person ={
      name:"Kevin",
      age:31,
      5:"Test"
};
alert(person.name);
alert(person["5"]);

3. 使用工厂模式建立对象;

返回带有属性和方法的person对象。

function createPerson(name, age,job){
    var o = new Object();
    o.name=name;
    o.age=31;
    o.sayName=function()
    {
        alert(this.name);
    };
    return o;
}
createPerson("kevin",31,"se").sayName();

用函数来封装以特定接口建立对象的细节,解决了建立多个类似对象的问题可是没有解决对象识别的问题(怎么知道一个对象的类型)。javascript

4. 使用自定义构造函数模式建立对象;

这里注意命名规范,做为构造函数的函数首字母要大写,以区别其它函数。这种方式有个缺陷是sayName这个方法,它的每一个实例都是指向不一样的函数实例,而不是同一个。构造函数模式,构造函数添加属性和方法,使用的时候new一个自定义的对象

function Person(name,age,job)
{
    this.name=name;
    this.age=age;
    this.job=job;
    this.sayName=function()
    {
        alert(this.name);
    };
}

var person = new Person("kevin",31,"SE");
person.sayName();

new一个构造函数的内部操做步骤:java

1)、建立一个新对象;编程

2)、将构造函数的做用域赋给新对象(所以this就指向了这个新对象);函数

3)、执行构造函数中的代码;this

4)、返回新对象。spa

使用构造函数建立的实例,都会有一个constructor属性,指向构造函数。prototype

建立自定义的构造函数意味着未来能够将它的实例标识为一种特定的类型。这正是赛过工厂模式的地方。指针

与普通函数的区别在于new调用,不用new来调用,与普通函数无差。code

不使用new调用的时候,就至关于window调用了构造函数,属性和方法都被添加到了window对象上去。对象

也能够这样使用:(call就是为了改变上下文环境而生)

var o = new Object();
Person.call(o,"Dadaoshenyi",25,"Enginner");
o.sayName();//"Dadaoshenyi"

构造函数建立对象的问题:每一个方法都要在实例上重写一遍。因为函数也是对象,所以每次定义一个函数,也就实例化了一个对象。

5. 使用原型模式建立对象;

解决了方法4中提到的缺陷,使不一样的对象的函数(如sayFriends)指向了同一个函数。

但它自己也有缺陷,就是实例共享了引用类型friends,从下面的代码执行结果能够看到,两个实例的friends的值是同样的,这可能不是咱们所指望的。原型模式,定义构造函数,构造函数原型上添加属性和方法。 

function Person(){

}

Person.prototype = {
    constructor : Person,
    name:"kevin",
    age:31,
    job:"SE",
    friends:["Jams","Martin"],
    sayFriends:function()
    {
        alert(this.friends);
    }
};
var person1 = new Person();
person1.friends.push("Joe");
person1.sayFriends();//Jams,Martin,Joe
var person2 = new Person(); 
person2.sayFriends();//James,Martin,Joe

构造函数的原型||对象实例的内部指针([[Prototype(__proto__)]]指向Person.prototype)。

实例对象的内部指针指向构造函数的原型。

原型模式的优势:自定义的构造函数,可让全部的对象实例共享原型对象所包含的属性和方法。原生的引用类型也是采用这种模式。

问题在于:一、省略了构造函数传递参数的步骤。二、全部实例共享方法和属性,这样,实例修改原来的属性或者方法,将会在全部的实例上表现出来。被捆绑到了一块儿。只是一个引用,不是一个副本。

6. 组合使用原型模式和构造函数建立对象;

解决了方法5中提到的缺陷,并且这也是使用最普遍、认同度最高的建立对象的方法。组合使用构造函数模式和原型模式,最经常使用的一种模式。 

function Person(name,age,job)
{
    this.name=name;
    this.age=age;
    this.job=job;
this.friends=["Jams","Martin"]; } Person.prototype.sayFriends=function() { alert(this.friends); };
  // Person.prototype = {
     // constructor: Person,
     // sayFriends: function() {
        // alert(this.friends);
     // }
  // };
var person1 = new Person("kevin",31,"SE");
var person2 = new Person("Tom",30,"SE");
person1.friends.push("Joe");
person1.sayFriends();//Jams,Martin,Joe
person2.sayFriends();//Jams,Martin

优势:使用构造函数来建立实例属性,且能够修改设定的值。使用原型建立共享方法和共享的属性。最大限度的节省了内存。

7. 动态原型模式;

这个模式的好处在于看起来更像传统的面向对象编程,具备更好的封装性,由于在构造函数里完成了对原型建立。这也是一个推荐的建立对象的方法。动态原型模式,将上面的对象原型方法||属性的建立方法哦了构造函数里面完成。具备更好的封装性。结果是同样的。 

function Person(name,age,job)
{
    //属性
    this.name=name;
    this.age=age;
    this.job=job;
    this.friends=["Jams","Martin"];
    //方法
    if(typeof this.sayName != "function")
    {
        Person.prototype.sayName=function()
        {
            alert(this.name);
        };
        
        Person.prototype.sayFriends=function()
        {
            alert(this.friends);
        };
    }
}

var person = new Person("kevin",31,"SE");
person.sayName();
person.sayFriends();

另外还有两个建立对象的方法,寄生构造函数模式和稳妥构造函数模式。因为这两个函数不是特别经常使用,这里就不给出具体代码了。

写了这么多建立对象的方法,其实真正推荐用的也就是方法6和方法7。固然在真正开发中要根据实际须要进行选择,也许建立的对象根本不须要方法,也就不必必定要选择它们了。

相关文章
相关标签/搜索