zoukankan      html  css  js  c++  java
  • javascript面向对象(二)

    创建对象


    要创建一个对象我们可以用如下代码:

    var user = new Object();  
    user.name = '编程浪子';
    user.age = 22;
    user.address = '四川成都';  

    用这样的方法创建对象比较简单直观,也是JavaScript种创建对象最基本的方法。但是这样就有一个问题,如果我们需要创建多个对象,那么我就得写很多重复的代码。比如我们想创建另一个对象user1,我们就得重新将上面的代码重新写一遍,这在实际开发过程中是不合适的,这样如果对象过多,代码量将大大增加。

    为了解决这样的问题,我们可以使用一种叫做工厂模式的方法,这种方法 就是为了解决实例化对象产生大量重复代码的问题。

    工厂模式

    function create(name, age) {
      var obj = new Object(); 
      obj.name = name; 
      obj.age = age;
      obj.show = function () {
        return this.name +' '+ this.age;
      };
      return obj;
    }
    var obj1= create('bclz', 30);    //第一个实例
    var obj2= create('bcxb', 20);    //第二个实例
    alert(obj1.show());
    alert(obj2.show());  

    从上面的代码我们可以看出,工厂模式解决了实例化时代码大量重复的问题,但又出现了一个问题,那就是识别问题,我们根本无法弄清楚他们到底是哪个对象的实例。比如

    alert(typeof obj1);  //Object
    
    alert(obj1 instanceof Object);  //true

    以上代码标明obj1是Object对象,但是我们无法知道具体是哪一个对象创建的。

    构造函数(构造方法)

    function User(name, age) {    //构造函数模式
      this.name = name;
      this.age = age;
      this.show = function () {
        return this.name  + ' '+this.age;
      };
    }  

    创建对象的时候用new运算符就可以了:

    var user1 = new User('bclz', 30);    //第一个实例
    var user2 = new User('bcxb', 20);    //第二个实例

    现在我们就可以检测user1或者user2是不是属于User。

    alert(user1 instanceof User);//true

    可见,使用构造函数的方法,即解决了重复实例化的问题,又解决了对象识别的问题。

    要创建User对象的新实例,就要使用new操作符,使用这个方式构建实例对象,会经过下面4个步骤:

    1.创建一个新对象;

    2.将构造函数的作用域给新对象(因此this指向的这个新对象)。

    3.执行构造函数内的代码在(为新对象添加属性);

    4.返回新对象。

    不过需要注意下面两个问题:

    构造函数也是函数
    构造函数与函数的唯一区别,就是调用方式的不同,不过,构造函数毕竟也是函数,不存在什么特殊的定义构造函数的语法。任何函数,只要通过new操作符来调用,就可以把它看作是构造函数;而任何函数,如果不通过new操作符调用,它就和普通函数没有什么区别,例如前面定义的User:

    //当作构造函数调用
    var user1 = new User('bclz', 30);  
    user1.show(); //bclz 30;
    
    //当作普通函数调用
    User('bclz', 30);
    window.show(); //bclz 30;  

    结果上没有什么区别,只是大家可以看到,当作普通函数调用的话,函数里this对象的指向,其实是指向的window全局对象。而通过new关键字调用,this指向的则是新对象而已,所以,其实还可以这么来写:

    var o = new Object();
    User.call(o,'bclz', 30);
    o.show();  

    通过函数方法call来重新定义对象的作用域,这里不多做解释,讲到函数细节时再仔细介绍这种方法,这里只是说明可以改变对象的作用域的,其实就是改变this的指向

    构造函数的问题

    构造函数的模式虽然好,但是并非没有缺点。构造函数最大的问题就是,每个方法都要在实例上重新创建一次。在前面的例子中,user1和user2中都有一个show方法,如果我们执行以下语句:

    alert(user1.show==user2.show);//结果返回的是false

    结果返回的是false,这就说明方法其实也是一种引用地址。如果我们同样重复创建了多个对象,那么每个对象中的方法都会在内存中开辟新的空间,这样浪费的空间就比较多。要解决这个问题,我们就需要用到实例属性或者方法的共享。 我们可以使用一种变通的方式,来达到我们想要的效果,也就是让show方法不再重复创建

    function User(name, age) {    
      this.name = name;
      this.age = age;
      this.show = show;
    } 
    function show(){
        alert(this.name + ' ' + this.age);
    }  

    将show方法移到外部,相当于show方法成了一个全局函数,然后再到User构造函数内部去引用show方法,这样User内部的this.show都指向了同一个全局函数show,因此,我们实例化的user1和user2就实现了共享,可以再次调用:

    alert(user1.show==user2.show);//结果返回的是true  

    但是这只是一个测试,如果你要让更多的属性或者方法实现共享,那不是要定义更多的全局函数或者变量,这种方式是不科学也不可行的。因此,我们需要引入另外一个javascript面向对象的重要概念原型

  • 相关阅读:
    matlab矩阵中如何去掉重复的行;如何找到相同的行,并找到其位置
    Coursera 机器学习 第9章(下) Recommender Systems 学习笔记
    机器学习基石笔记1——在何时可以使用机器学习(1)
    Coursera 机器学习 第9章(上) Anomaly Detection 学习笔记
    matlab安装过程的被要求的配置程序
    jdk环境变量配置
    Coursera 机器学习 第8章(下) Dimensionality Reduction 学习笔记
    Coursera 机器学习 第8章(上) Unsupervised Learning 学习笔记
    Coursera 机器学习 第7章 Support Vector Machines 学习笔记
    linux服务器---squid限制
  • 原文地址:https://www.cnblogs.com/5huihui/p/4104287.html
Copyright © 2011-2022 走看看