zoukankan      html  css  js  c++  java
  • JavaScript创建对象的几种方式总结

      ECMA把对象定义为:无序属性的集合,其属性可以包含基本值、对象或者函数。

    1. 使用Object构造函数创建对象

      创建自定义对象的最简单的方式就是创建一个Object的实例,然后再为它添加属性和方法。

    //通过Object构造函数的实例创建对象
    var person = new Object();
    //添加属性和方法
    person.name = "guo";
    person.age = '24';
    person.sayName = function(){
        console.log(this.name);
    };
    //访问属性的两种方式:点表示法和方括号表示法
    console.log(person.name);  //"guo"
    console.log(person['age']); //24
    person.sayName();  //"guo"

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

    //使用对象字面量创建一个对象
    var person = {
        name : "guo",
        age : 24,
        sayName : function(){
            console.log(this.name);
        }
    };
    console.log(person.name);  //"guo"
    console.log(person['age']); //24
    person.sayName();  //"guo"

    3.工厂模式 

      虽然Object构造函数或者对象字面量都可以用来创建单个对象,但这些方式有个明显的缺点:使用同一个接口创建对象,会产生大量的重复代码。为了解决这个问题,提出工厂模式。

    //使用工厂模式创建对象,返回带有属性和方法的person对象
    function createPerson(name, age){
        var o = new Object();
        o.name = name;
        o.age = age;
        o.sayName = function(){
            console.log(this.name);
        };
        return o;
    }
    var person1 = createPerson("guo", 24);
    person1.sayName(); //"guo"

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

    // 使用自定义构造函数模式创建对象(作为构造函数的函数首字母要大写,以区别其它函数)
    function Person(name,age){
        this.name=name;
        this.age=age;
        this.sayName=function(){
            console.log(this.name);
        };
    }
    
    var person1 = new Person("guo", 24);
    person1.sayName(); //"guo”

    拓展:要创建Person的新实例,必须使用new操作符。那么,new操作符具体干了些什么呢?

    (1)创建一个新(空)对象

    (2)将构造函数的作用域赋给新对象(因为this就指向了这个新对象)

    (3)执行构造函数中的代码(为这个新对象添加属性)

    (4)返回新对象

    构造函数和其他函数的唯一区别:就在于调用它们的方式不同。任何函数,只要通过new操作符来调用,那它就可以作为构造函数;而任何函数,如果不通过new操作符来调用,那它跟普通函数也不会有什么区别。这种方式有个缺陷是,上面例子中,sayName这个方法,它的每个实例都是指向不同的函数实例,而不是同一个。即不同实例上的同名函数是不相等的

      为了解决这个问题,提出了原型模式创建对象。

    5.使用原型模式创建对象

    //使用原型模式创建对象(解决了构造函数中的函数无法复用问题)
    function Person(){
    }
    
    Person.prototype = {  //对象字面量语法 重写原型对象
        constructor : Person,   
        name : "guo",
        age : 24,
        friends:["liu","li"],
        sayName:function(){
            console.log(this.name);
        }
    };
    //创建实例1
    var person1 = new Person();
    person1.friends.push("yang"); 
    console.log(person1.friends);  //[ 'liu', 'li', 'yang' ]
    //创建实例2
    var person2 = new Person(); 
    console.log(person2.friends);  //[ 'liu', 'li', 'yang' ]  //原型模式的缺陷
    
    person1.sayName(); //"guo"
    person2.sayName(); //"guo"

      这里我们发现了一个问题,而是原型模式的缺陷,上面例子中,person1改变数组的值,直接影响了person2中friends数组的值,这是我们不希望看到的。

      原型模式最大的问题是由共享的本质所导致的,原型中所有的属性是被所有实例共享的。对于引用类型的值,也出现了实例共享问题。

      为了解决这个问题,提出了组合使用原型模式和构造函数创建对象。

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

      顾名思义,构造函数用于定义实例属性,而原型模式用于定义方法和共享的属性。

    //组合使用原型模式和构造函数创建对象(使用最广泛、认同度最高)
    //构造函数用于定义实例属性,而原型模式用于定义方法和共享的属性
    function Person(name,age){
        this.name = name;
        this.age = age;
       this.friends = ["liu","li"];
    }
    Person.prototype = {
        constructor : Person,
        sayName : function(){
            console.log(this.name);
        }
    }
    var person1 = new Person("guo", 24);
    var person2 = new Person("zhu", 30);
    person1.friends.push("yang");
    
    console.log(person1.friends);  //[ 'liu', 'li', 'yang' ]
    console.log(person2.friends);  //[ 'liu', 'li' ]
    person1.sayName();//"guo"
    person2.sayName();//"zhu"

    7.动态原型模式

    //动态原型模式(具有更好的封装性)
    function Person(name, age){
        //属性
        this.name = name;
        this.age = age;
        this.friends = ["liu","li"];
        //方法
        if(typeof this.sayName !="function"){
            Person.prototype.sayName=function(){
                console.log(this.name);
            }
        }
    }
    
    var person1 = new Person("guo", 24);
    console.log(person1.friends);  //[ 'liu', 'li' ]
    person1.sayName(); //"guo"

      另外还有两个创建对象的方法,寄生构造函数模式稳妥构造函数模式。由于这两个函数不是特别常用,这里就不给出具体代码了。有兴趣可以查看 js高程P160-162

    总结

      ECMAScript 支持面向对象(OO)编程,但不使用类或者接口。对象可以在代码执行过程中创建和增强,因此具有动态性而非严格定义的实体。在没有类的情况下,可以采用下列模式创建对象。

    (1)工厂模式,使用简单的函数创建对象,为对象添加属性和方法,然后返回对象。这个模式后来被构造函数模式所取代。

    (2)构造函数模式,可以创建自定义引用类型,可以像创建内置对象实例一样使用new 操作符。不过,构造函数模式也有缺点,即它的每个成员都无法得到复用,包括函数。由于函数可以不局限于任何对象(即与对象具有松散耦合的特点),因此没有理由不在多个对象间共享函数。

    (3)原型模式,使用构造函数的prototype 属性来指定那些应该共享的属性和方法。组合使用构造函数模式和原型模式时,使用构造函数定义实例属性,而使用原型定义共享的属性和方法。

  • 相关阅读:
     sublime text3快速生成html头部信息(转)
    电脑同时安装Python2和Python3以及virtualenvwrapper(转)
    在windows下使用多版本Python安装相应的虚拟开发环境
    win10+wget 收藏
    关于OS_PRIO_SELF的说明
    select菜单实现二级联动
    HeadFirst设计模式笔记:(六)命令模式 —— 封装调用
    rnqoj-57-找啊找啊找GF-二维背包
    UILable:显示多种颜色的方法
    动态规划晋级——POJ 3254 Corn Fields【状压DP】
  • 原文地址:https://www.cnblogs.com/guorange/p/7225258.html
Copyright © 2011-2022 走看看