创建对象的方法

备注:这里对于用字面量形式和Object构造函数就不做过多的声明

工厂模式

    function createPerson (name,age,sex) {  
        var o = new Object();
        o.name = name;
        o.age =  age;
        o.sex = sex;
        return o;
    }  
    var person1 = createPerson('sam',20,'man');

这种方式本质上其实就是对Object构造函数多加了一层封装

构造函数模式

    function Person(name,age,sex){  
        this.name = name;
        this.age = age;
        this.sex = sex;
        this.say = function(){
            return 'say hello'
        }
    }
    //创建
    var person = new Person('sam',20,'man')

使用构造函数的缺点是每创建一次实例,函数内部的方法都会重新构建一次,对于私有方法来说这是可行的,但对于一些公用的实现相同功能的方法频繁去实例化是没有必要的。

原型模式

    function Person(){};
    Person.prototype.name = 'name';
    Person.prototype.age = 'age';
    Person.prototype.job = ['student','teacher'];
    var person = new Person();  

原型模式的问题是所有实例共享属性和方法,对于只是添加一个原型上存在的同名属性而言,是会隐藏原型上的属性,这个时候的影响不会特别大。但是对于引用类型的数据,如果只是在修改数据,就会带来比较大的影响。比如:

    var person1 = new Person();
    var person2 = new Person();
    person1.job.push('leader');  
    //person1.job: 'student','teacher','leader  
    //person2.job: 'student','teacher','leader'

如上所示,在person1的实例上我们修改了job数组,此时打印出的person2的job也发生了改变,这可能并不是我们所希望看到的。通常来说我们都希望每个实例都有自己的属性定义,这个时候单纯使用原型模式就不是很适合。

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

    function Person(name,age,sex){
        this.name = name;
        this.age = age;
        this.sex = sex;
    }
    Person.prototype.getName = function(){
        return 'hello' + this.name;
    }
    var person = new Person('sam',20,'sex');
    person.getName(); // hello sam

这种方式结合了构造函数和原型方式的优点,私有方法定义在函数内部,公有属性和方法定义在原型上。避免了原型造成属性共享的问题,也加强了对象的扩展性,这也是目前使用最广泛的创建自定义函数类型的方式。

你可能感兴趣的:(创建对象的方法)