zoukankan      html  css  js  c++  java
  • 创建对象的常用四种模式和优缺点

    一、工厂模式

            function createCar(color,type){
                var car = new Object();
                car.color = color;
                car.type = type;
                car.sayColor = function(){
                    alert(this.color);
                };
                return car;
            }
            var car1 = createCar('red','CDV');
            var car2 = createCar('blue','SUV');
            car1.sayColor();  //red
            car2.sayColor();  //blue
            console.log(car1);
            console.log(car2);
    

      运行结果:

    1.  特点:用函数来封装创建对象的细节,内部最终返回一个对象。  

    2.  优点:解决了创建多个相似对象的问题

    3.  缺点:不能确定对象的类型(即无法用 instanceof 去判断)

    二、构造函数模式

            function Car(color,type){
                this.color = color;
                this.type = type;
                this.sayColor = function(){
                    alert(this.color);
                };
            }
            var car1 = new Car('red','CDV');
            var car2 = new Car('blue','SUV');
            car1.sayColor();  //red
            car2.sayColor();  //blue
            console.log(car1);
            console.log(car2);
            console.log(car1 instanceof Car);
    

      1、特点:

      • 没有显式创建对象
      • 属性和方法赋给了this
      • 没有 return 语句

      2、调用过程:

      • 使用new操作符创建一个新对象
      • 将构造函数的作用域赋给新对象(this就指向了新对象)
      • 执行构造函数里的代码
      • 返回新对象

      3、优点:可将实例标识为一种特定类型(比如car1的类型就是Car,可用instanceof判断)

      4、缺点:每个方法都要在每个实例上重新创建一遍。可以将其写在外部共享,但又失去了封装性。如下:

            function Car(color,type){
                this.color = color;
                this.type = type;
            }
    
            function sayColor(){
                alert(this.color);
            }
            var car1 = new Car('red','CDV');
            var car2 = new Car('blue','SUV');
            sayColor.call(car1);  //red,这里通过call来改变作用域
            sayColor.call(car2);  //blue,这里通过call来改变作用域
            console.log(car1);
            console.log(car2);
            console.log(car1 instanceof Car);
    

      

    三、原型模式

            function Car(){
            }
            Car.prototype.color = 'red';
            Car.prototype.type = 'SUV';
            Car.prototype.sayColor = function(){
                alert(this.color);
            }
            var car1 = new Car();
            var car2 = new Car();
            
            car1.sayColor(); //red 来自原型
            car2.sayColor(); //red 来自原型
            car1.color = 'blue'; //屏蔽了原型的color,但没有覆盖,原型的color还在
            alert(car1.color);  //blue 来自实例
            alert(car2.color);  //red  来自原型
    

      1、原型、构造函数与实例的关系:每个构造函数都有一个原型对象(prototype属性),原型对象包含一个指向构造函数的指针(constructor),实例包含一个指向原型对象的指针(__proto__)。实例与构造函数没有直接关系。

      2、访问一个对象属性的过程:在上面代码中,比如car2.color ,先问car2实例上有color属性吗?没有,则查找原型,car2原型上有color属性吗?有,则返回。再比如car1.color ,先问car1上有color属性吗?有,则返回。就不需要查找原型了。

      3、判断属性是否存在于实例中:hasOwnProperty() , true——实例

      4、优点:属性和方法可以共享,并且可以在实例上重新定义属性,而不改变原型。

      5、缺点:由于共享,对于引用类型,在实例上进行修改,也会改变原型的值。如下:

      

            function Person(){
            }
            Person.prototype = {
                constructor:Person,  //防止一些操作切断构造函数与原型的关系
                name:'Jemma',
                friends:['Lucy','Jack']
            }
            var person1 = new Person();
            var person2 = new Person();
            console.log(person1.name); //Jemma
            console.log(person2.name); //Jemma
            //改变基本类型的属性
            person1.name = 'King';
            console.log(person1.name); //King
            console.log(person2.name); //Jemma
            //改变引用类型
            person1.friends.push('Marry');
            console.log(person1.friends); //["Lucy", "Jack", "Marry"]
            console.log(person2.friends); //["Lucy", "Jack", "Marry"]
    

      

    四、构造函数+原型模式(一般使用这个)

            function Person(name,age){
                this.name = name;
                this.age = age;
            }
            Person.prototype = {
                constructor:Person,  //防止一些操作切断构造函数与原型的关系
                sayName:function(){
                    alert(this.name);
                }
            }
            var person1 = new Person('Jemma',19);
            var person2 = new Person('King',21);
            console.log(person1.name); //Jemma
            console.log(person2.name); //King
            person1.sayName(); //Jemma
            person2.sayName(); //King
    

      特点:所有实例共享的属性和方法原型中定义;自己独有的在构造函数定义。

      优点:既可以共享,又有特定类型。


      其实关于这些细节可以讲很多东西,我这里只是简单总结一下。

  • 相关阅读:
    基于GDAL库,读取.grd文件(以海洋地形数据为例)Java版
    基于GDAL库,读取.nc文件(以海洋表温数据为例)C++版
    基于UDP传输协议局域网文件接收软件设计 Java版
    基于Oracle数据库登陆界面及功能实现 Java版
    ORM中的Model与DDD中的DomainModel
    探讨DDD中角色权限与DCI的使用
    哈工大软件构造 复习
    python列表的基本用法
    matlab简单的超越方程求解近似值
    MATLAB一些常用的function
  • 原文地址:https://www.cnblogs.com/jelina/p/11180863.html
Copyright © 2011-2022 走看看