zoukankan      html  css  js  c++  java
  • JS创建对象的几种方法

    言归正传,本文讨论几种js创建对象的方法,先从最好理解的工厂模式开始:

    复制代码
    function createPerson(name,age,job){
        var o = {};
        o.name = name;
        o.age = age;
        o.job = job;
        o.sayName = function(){
         alert(this.name);
        };
        return o;
    }
    
    var tanya = createPerson("tanya","30","female");
    var ansel = createPerson("ansel","30","male");
    
    tanya.sayName();
    ansel.sayName();
    复制代码

    这里先定义o为一个空的对象,然后为o设置了一堆属性。其实也可以直接给o属性的嘛,所以如果这样写也是ok的。

    复制代码
    function createPerson(name,age,job){
        var o = {
            name : name,
            age : age,
            job : job,
            sayName : function(){
             alert(this.name);
            }
        };
        return o;
    }
    
    var tanya = createPerson("tanya","30","female");
    var ansel = createPerson("ansel","30","male");
    
    tanya.sayName();
    ansel.sayName();
    复制代码

    还有一种办法是利用无敌的this,因为this就表示当前运行时的对象,将构造函数this的作用域指向新对象,将当前运行对象的属性和方法都赋给新对象,这样对象模式称为构造函数模式

    复制代码
    function Person(name,age,job){
        this.name = name;
        this.age = age;
        this.job = job;
        this.sayName = function(){
         alert(this.name);
        };
    }
    
    var tanya = new Person("tanya","30","female");
    var ansel =  new Person("ansel","30","male");
    
    tanya.sayName();
    ansel.sayName();
    复制代码

    在这个例子中,tanya和ansel都有一个constructor属性,该属性指向person。

    考虑一下如下的情况:

    复制代码
    function Person(name,age,job){
        this.name = name;
        this.age = age;
        this.job = job;
        this.sayName = function(){
         alert(this.name);
        };
    }
    
    Person("tanya","30","female");
    Person("ansel","30","male");
    
    window.sayName();
    window.sayName();
    复制代码

    发现两次弹出的都是ansel,这是因为不用new的话,就不是一个person的实例,而仅仅在执行函数。而在全局作用域调用一个函数时this总是指向Global对象。而Global对象在浏览器中就是window对象。

    我们还可以用构造模式在另外一个对象中调用sayName方法,还记得Apply和call么,来吧再考虑另外一种情况,

    复制代码
    function Person(name,age,job){
        this.name = name;
        this.age = age;
        this.job = job;
        this.sayName = function(){
         alert(this.name);
        };
    }
    
    var olivia = {};
    Person.call(olivia,"tanya","30","female");
    olivia.sayName();
    
    var philip = {}
    Person.apply(philip,["ansel","30","male"]);
    philip.sayName();
    复制代码

    原型模式就要考虑原型链了,分析一下,sayName方法在实例中被重复定义了两次,但其实没有必要创造两个一样的副本。使用原型方法,可以使是tanya和ansel的共享一个sayName方法。

    于是原型模式的写法如下:

    复制代码
    function Person(name,age,job){
        this.name = name;
        this.age = age;
        this.job = job;
    }
    
    Person.prototype.sayName= function(){
         alert(this.name);
        };
    
    var tanya = new Person("tanya","30","female");
    var ansel =  new Person("ansel","30","male");
    
    tanya.sayName();
    ansel.sayName();
    复制代码

    实际应用时,不是一成不变的套用某种模式,活学活用。需要共享方法的时候就用原型模式,需要使用副本的时候就用构造模式,还可以结合起来,把所有信息都封装在构造函数中,而通过在构造函数中初始化原型,使得对象保持了同时使用构造函数和原型的优点。

    复制代码
    function Person(name,age,job){
        this.name = name;
        this.age = age;
        this.job = job;
        if (typeof sayName != "function" ){
                Person.prototype.sayName= function(){
                alert(this.name);
            };
        }
    }
    
    var tanya = new Person("tanya","30","female");
    var ansel =  new Person("ansel","30","male");
    ansel.sayName = function () {
        alert("Hi ansel, how hansome you are!");
    }
    
    tanya.sayName();
    ansel.sayName(); 
  • 相关阅读:
    asp.net string有多行文字
    asp.net设置gridview页码显示遇到的问题
    asp.net button浏览器端事件和服务器端事件
    GridView 控制默认分页页码间距 及字体大小
    复合主键与联合主键(转载)
    vsCode 列选择、列选中、选中列、选中多列(转载)
    可能有用的技术社区(转载)
    SQL 用于各种数据库的数据类型(转载) sqlserver 数据类型 取值范围 长度
    TypeError: value.getTime is not a function (elementUI报错转载 )
    工作1年3个月总结(201707-201810 )
  • 原文地址:https://www.cnblogs.com/zxktxj/p/2586663.html
Copyright © 2011-2022 走看看