面向面试编程——javascript对象的几种建立方式

javascript对象的几种建立方式javascript

总共有如下几个模式:java

1.工厂模式

2.构造函数模式

3.原型模式

4.混合构造函数和原型模式

5.动态原型模式

6.寄生构造函数模式

7.稳妥构造函数模式

1.工厂模式:windows

<script type="text/javascript">

     function Person(name,sex)
     {
         var obj=new Object();

         obj.name=name;
         obj.sex=sex;
         obj.getSex=function(){
             alert(this.sex);
         }
         return obj;
     }
    var person=new Person("张三","男")
    
    alert(person.name);
    person.getSex();
</script>

缺点:不能识别出对象的类型。数组

2.构造函数模式安全

<script type="text/javascript">
    function Person(name,sex)
    {
        this.name=name;
        this.sex=sex;
        this.getSex=function(){
            alert(this.sex);
        }
    }

    var person=new Person('张三','男');
    alert(person.name);
    person.getSex();

</script>

使用构造函数模式能够有三种创造方式:app

(1)看成构造函数去使用函数

   var person=new Person();this

 (2) 看成普通函数去使用spa

      var person=Person();可是这种方式默认this是windows,至关于直接在全局范围内定义name,sex属性。prototype

 (3)使用call

    var person=new Object();

        Person.call(person,"张三","男");

   alert(person.name);  //张三

缺点:因为this指针在对象实例的时候发生改变指向新的实例。这时新实例的方法也要从新建立,若是n个实例就要n次重建相同的方法

3.原型模式

<script type="text/javascript">
    function Person()
    {
        
    }
    Person.prototype={
        constructor:Person, //必须设置这个属性,否则就断了与构造函数的联系了。没有实例共享原型的意义了。
        /*
        如今这个属性是可枚举的,若不想被枚举,则能够使用以下代码
        参数:重设构造器的对象,所要设置的属性,可选设置
        Object.definePropery(Person.prototype,'constructor',{
            enumerable:false,
            value:Person
        })

        */
        name:'张三',
        sex:'男',
        getSex:function(){
            alert(this.sex);
        }
    }

    var person=new Person();
    alert(person.name);
    person.getSex();

</script>

调用方法的过程:先看实例中有没有,有调之,无追踪到原型,有调之,无出错,调用失败。

缺点:这种纯原型的模式问题也很明显,全部的属性,方法和变量都是共享的,一旦修改一个所有都会受影响,不能让对象具体化。

4.混合构造和原型模式

<script type="text/javascript">
    function Person(name,sex)
    {
        this.name=name;
        this.sex=sex;
    }
    Person.prototype={
        constructor:Person, //必须设置这个属性,否则就断了与构造函数的联系了。没有实例共享原型的意义了。
        /*
        如今这个属性是可枚举的,若不想被枚举,则能够使用以下代码
        参数:重设构造器的对象,所要设置的属性,可选设置
        Object.definePropery(Person.prototype,'constructor',{
            enumerable:false,
            value:Person
        })

        */
     
        getSex:function(){
            alert(this.sex);
        }
    }

    var person=new Person("张三","男");
    alert(person.name);
    person.getSex();

</script>

推荐:应用最普遍。

5.动态原型模式

<script type="text/javascript">
    function Person(name,sex)
    {
        this.name=name;
        this.sex=sex;

        //动态原型方法  只会执行一次
        if(typeof this.getSex!='function')
        {
            Person.prototype.getSex=function(){
                alert(this.sex);
            }
        }
    }
    

    var person=new Person("张三","男");
    alert(person.name);
    person.getSex();

</script>

推荐

5.寄生构造函数模式

这种模式的基本思想是建立一个函数,该函数的做用仅仅是封闭建立对象的代码,而后再返回新建立的对象.

假设咱们想建立一个具备额外方法的特殊数组。因为不能直接修改Array构造函数,能够使用这个模式。

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;

在这个例子中,咱们建立了一个名叫SpecialArray的构造函数。在这个函数内部,首先建立了一个数组,而后push()方法(用构造函数接收到的全部参数)初始化了数组的值。随后,又给数组实例添加了一个toPipedString()方法,该方法返回以竖线分割的数组值。最后,将数组以函数值的形式返回。接着,咱们调用了SpecialArray构造函数,向其中传入了用于初始化数组的值,此后调用了toPipedString()方法。

关于寄生构造函数模式,有一点须要说明:首先,返回的对象与构造函数或构造函数的原型属性之间没有关系;也就是说,构造函数返回的对象与在构造函数外部建立 对象没有什么不一样。为此,不能依赖instranceof操做符来肯定对象类型。因为存在上述问题,建议在能够使用其余模式的状况下,不要使用这种模式。

6.稳妥构造函数模式

<script type="text/javascript">
    function Person(name,sex)
    {
       var object=new Object();
       var name=name;
       var sex=sex;
       object.getSex=function(){
               alert(sex);
       }
       return object;
    }
    

    var person=new Person("张三","男");
    alert(person.name);  //undefined
    person.getSex();     //

</script>

没有公共属性,其余方法也不引用this对象,只能经过存取器得到变量的值,适合对安全性要求很高的程序。

还有不能被称为模式的方法,只能实例单个对象:

1.简单对象字面量

//建立一个简单对象字面量
var person = {};    

// 加入属性和方法
person.name = 'ifcode';
person.setName = function(theName) {
   person.name = theName;
}

很是简单,但通常状况下不推荐这种方法。JS good parts书中认为这种写法可读性不够强,做者推荐的是后面一种写法。

2.嵌套对象字面量

var person = {
    name: 'ifcode',
    setName: function(theName) {
        this.name = theName;
    }
}
JS good parts中推荐这种写法:
相关文章
相关标签/搜索