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

     

    javascript面向对象(一)

    对象其实就是一种引用类型。而对象的值就是引用类型的实例。在JavaScript 中引用类型是一种数据结构,将数据和功能组织在一起。

    它也常被称做为类,但JavaScript 中却没有类的概念。虽然JavaScript 是一门面向对象的语言,却不具备传统面向对象语言所支持的类和接口等基本结构。

    对象的创建以及常用操作

    1. 使用new运算符

      var user = new Object();        //使用new运算符创建一个对象
      user.name = '李铭';        //给对象添加属性
      user.age = 21;
      user.address = '四川成都';  
      
    2. 对象字面量(JSON方式)

      var user = {
          name:'王五',
          age:22,
          address:'四川成都'    
      };  
      
    3. 简单方式(传统赋值方式)

      var user = {};
      user.name = '王五';        //给对象添加属性
      user.age = 22;
      user.address = '四川成都';
      
    4. 属性的调用

      对于对象属性的调用有两种方式:

      调用方法如下:

      alert(user.name + " " +user.age);

    5. //返回 '王五四川成都'

      另一种方法:

      alert(user['name'] + " " +user['age']);

    6. //返回 '王五四川成都'

    7. 添加方法

      var user = {
              name:'王五子',        //给对象添加属性
              age:22,
              address:'四川成都',
              showInfo:function(){//添加一个方法
                  alert(this.name+" "+this.age+" "+this.address);
              },
              showHello:showHello//将对象外部的方法添加到对象
          };
          function showHello(){
              alert("Hello!");    
          }
          user.showInfo();//调用方法
          user.showHello();  

     

    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面向对象的重要概念原型

    Javascript 面向对象编程(一):封装

    把两个属性封装在一个对象里面。但是,这样的写法有两个缺点,一是如果多生成几个实例,写起来就非常麻烦;二是实例与原型之间,没有任何办法,可以看出有什么联系。

    例子:

    var cat1 = {}; // 创建一个空对象

        cat1.name = "李密昂"; // 按照原型对象的属性赋值

        cat1.age= "20

      var cat2 = {};

        cat2.name = "三毛";

        cat2.age= "19";

    那么问题来了,我们可以写一个函数,解决代码重复的问题吗?当然可以。

    function Cat(name,color){

        return {

          name:name,

                    age:age

        }

      }

    然后调用函数:

      var cat1 = Cat("李密昂","20");

      var cat2 = Cat("三毛","19");

    构造函数模式

    所谓"构造函数",其实就是一个普通函数,但是内部使用了this变量。对构造函数使用new运算符,就能生成实例,并且this变量会绑定在实例对象上。

    原型对象现在可以这样写:

    function Cat(name,color){

        this.name=name;

        this.age=age;

      }

    生成实例对象:

    var cat1 = new Cat("李铭","20");

      var cat2 = new Cat("三毛","19");

      alert(cat1.name); // 李铭

      alert(cat1.age); // 20

    这时cat1和cat2会自动含有一个constructor属性,指向它们的构造函数。

    alert(cat1.constructor == Cat); //true

      alert(cat2.constructor == Cat); //true

    Prototype模式

    Javascript规定,每一个构造函数都有一个prototype属性,指向另一个对象。这个对象的所有属性和方法,都会被构造函数的实例继承。

    这意味着,我们可以把那些不变的属性和方法,直接定义在prototype对象上。

    function Cat(name,age){

        this.name = name;

        this.age= age;

      }

      Cat.prototype.type = "猫科动物";

      Cat.prototype.eat = function(){alert("吃老鼠")};

    生成实例:

    var cat1 = new Cat("李铭","20");

      var cat2 = new Cat("三毛","19");

      alert(cat1.type); // 猫科动物

      cat1.eat(); // 吃老鼠

    指向prototype对象“

    alert(cat1.eat == cat2.eat); //true

    (未完待续。。。。。)

  • 相关阅读:
    POJ 1811 Prime Test 素性测试 分解素因子
    sysbench的安装与使用
    电脑中已有VS2005和VS2010安装.NET3.5失败的解决方案
    I.MX6 show battery states in commandLine
    RPi 2B Raspbian system install
    I.MX6 bq27441 driver porting
    I.MX6 隐藏电池图标
    I.MX6 Power off register hacking
    I.MX6 Goodix GT9xx touchscreen driver porting
    busybox filesystem httpd php-5.5.31 sqlite3 webserver
  • 原文地址:https://www.cnblogs.com/Duqinqin/p/4104574.html
Copyright © 2011-2022 走看看