zoukankan      html  css  js  c++  java
  • JS-最全的创建对象的方式

    JS最全创建对象方式汇总

    1.最简单的方式--创建一个Object实例

    1 var person = new Object();     //创建实例
    2 person.name = "BlueBeginner";  //给实例添加属性
    3 person.age = 21;               //添加属性
    4 person.sayName = function(){   //添加方法
    5     alert(this.name);
    6 }

    2.对象字面量

    var person = {
        name:'BlueBeginner',
        age:21,
        5:true,
        sayName:function(){
            alert(this.name);
        }
    }
    以上均为创建单个对象的方法,如果只需要少数具有不同属性和方法的对象,以上方法简单方便,但是当我们需要很多具有相似属性和方法的对象时,使用以上方法显然不切实际,因为会产生大量的重复代码。以下方法,便是为创建一类对象而生。

    3.工厂模式

    function createPerson(name,age,job){
        var o = new Object();//显式创建对象
        o.name = name;
        o.age = age;
        o.job = job;
        o.sayName = function(){
            alert(this.name);
        }
        return o;//返回对象
    }
    var personone = createPerson("BlueBeginner",21,"web Engineer");
    var persontwo = createPerson("DJL",23,"web Engineer");

    函数根据接受的参数来创建对应的对象,可以无数次的调用此函数,每次都会返回一个包含3个属性1个方法的对象。

    工厂模式注意:
    • 需要用var显式地创建对象
    • 有return语句,返回对象

    工厂模式没有解决对象的识别问题,我的理解是不能确定对象由哪个函数创建,看以下代码

    alert(personone instanceof createPerson);//false
    alert(personone instanceof Object);//true

    4.构造函数模式

    function Person(name,age,job){
        this.name = name;
        this.age = age;
        this.job = job;
        this.sayName = function(){
            alert(this.name);
        }
    }
    var personone = new Person("BlueBeginner",21,"web Engineer");
    var persontwo = new Person("DJL",23,"web Engineer");
    构造函数模式注意:
    • 没有显式地创造对象
    • 直接将属性和方法赋值给了this对象
    • 没有return语句
    • 构造函数名首字母大写
    • 使用new操作符创建实例
      • 创建一个新对象
      • 将构造函数的作用域赋给这个对象(因此this指向这个对象)
      • 执行构造函数中的代码
      • 返回新对象

    之所以说构造函数解决了工厂模式不能识别对象类型的问题,看下面的代码

    alert(personone.sayName == persontwo.sayName);//false
    这样的话,以上的两种模式都创建了两个完成同样任务的Function实例,这样做完全没必要。而且,对于构造函数模式,因为有this对象在,根本不用在执行代码前就把函数方法绑定到特定对象上面,大可像下面代码所示,将方法写到构造函数外面:
    function Person(name,age,job){
        this.name = name;
        this.age = age;
        this.job = job;
        this.sayName = sayName;
    }
    function sayName(){
        alert(this.name);
    }
    这样的话,所有实例共享了在全局作用域中定义的函数方法。但是很显然的是,如果需要很多很多方法呢?以这种方法,岂不是需要定义很多很多全局函数?在全局中定义的函数,只能被某些对象调用,这让全局作用域有点名不副实。好在,这些问题,可以通过原型模式来解决。

    5.原型模式

    function Person(){};
    Person.prototype.name = "BlueBeginner";
    Person.prototype.age = 21;
    Person.prototype.job = "web Engineer";
    Person.prototype.sayName = function(){
        alert(this.name);
    };
    var personone = new Person();
    var persontwo = new Person();
    personone.sayName();//'BlueBeginner'
    persontwo.sayName();//'BlueBeginner'
    alert(personone.sayName == persontwo.sayName);//true
    原型模式注意:
    • 所有实例共享相同的属性和方法
    • 对于方法和基本属性值,这样很合适,但是对于引用类型的值,却出现了问题。在实例中重写引用类型的值会修改原型中的同名属性。如下:
    function Person(){};
    Person.prototype = {
        constructor:Person,
        name:'BlueBeginner',
        age:21,
        friends:['DJL','ZH'],
        sayName:function(){
            alert(this.name);
        }
    }
    var personone = new Person();
    var persontwo = new Person();
    personone.friends.push('YR');
    alert(personone.friends);//'DJL','ZH','YR'
    alert(persontwo.friends);//'DJL','ZH','YR'
    alert(personone.friends == persontwo.friends);//true

    在第一的实例personone中重写引用类型值后,第二个实例所得到的原型上的引用类型值也被修改了,这显然不尽人意。所以很少有人单独使用原型模式。

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

    function Person(name,age,job){
        this.name = name;
        this.age = age;
        this.job = job;
        this.friends = ['DJL','ZH']
    }
    Person.prototype = {
        constructor:Person,
        sayName:function(){
            alert(this.name);
        }
    }
    var personone = new Person("BlueBeginner",21,"web Engineer");
    var persontwo = new Person("DJL",23,"web Engineer");
    personone.friends.push('YR');
    alert(personone.friends);//'DJL','ZH','YR'
    alert(persontwo.friends);//'DJL','ZH'
    alert(personone.sayName === persontwo.sayName);//true
    alert(personone.friends == persontwo.friends);//false

    这种模式将构造函数和原型分开,在构造函数里面写属性,在原型里面写方法,可以说,这是用来定义引用类型的一种默认模式,当然,有同学看到独立的构造函数和原型时,会感到困惑,下面这个模式,便解决了这个问题。

    7.动态原型模式

    function Person(name,age,job){
        this.name = name;
        this.age = age;
        this.job = job;
        if(typeof this.sayName != 'function'){
            Person.prototype.sayName=function(){
                alert(this.name);
            };
        };
    }

    这种模式方法确实非常完美,if判断代码只会在初次调用构造函数时才会执行,此后,原型已经初始化,不需要再做什么修改了。

    当然,第三版中还介绍了寄生构造函数模式和稳妥构造函数模式,但这两种模式用的很少,这里不多做介绍。有兴趣的同学请自行查阅相关资料。
  • 相关阅读:
    Vue 2.x windows环境下安装
    VSCODE官网下载缓慢或下载失败 解决办法
    angular cli 降级
    Win10 VS2019 设置 以管理员身份运行
    XSHELL 连接 阿里云ECS实例
    Chrome浏览器跨域设置
    DBeaver 执行 mysql 多条语句报错
    DBeaver 连接MySql 8.0 报错 Public Key Retrieval is not allowed
    DBeaver 连接MySql 8.0报错 Unable to load authentication plugin 'caching_sha2_password'
    Linux系统分区
  • 原文地址:https://www.cnblogs.com/zhouliang/p/6625029.html
Copyright © 2011-2022 走看看