• JavaScript面向对象编程


    一、引言
      长久以来,JavaScript在Web开发中一直处于被忽视的地位,甚至有相当一部分开发人员对它产生了误解,认为JavaScript只不过是用来完成一些花哨功能的雕虫小技。网络上广为流传的低质量的JavaScript代码对此也起到了推波助澜的作用...很多应用中JavaScript都采用了面向过程的编程方式,代码的可扩展性不好,复制粘贴的代码比比皆是...
      随着Ajax等技术的广泛使用,YUI、Prototype等对JavaScript的应用可谓是淋漓尽致、出神入化。人们才发现原来JavaScript可以实现如此强大的功能,具备如此优雅的架构...

    二、准备
    1、概念
    JavaScript是一种弱类型语言。包括:
    基本类型:数字Number,字符串String,布尔值Boolean;
    复合类型:对象Object,数组Array;
    工具类型:全局对象Global,日期Date,数学对象Math,正则表达式RegExp,错误对象Error;
    特殊类型:函数Function。

    这里我只想说两点:
    1)基本数据类型的包装对象
    每一个基本数据类型都有一个对应的对象类。可以灵活地实现类型转换。简单地说,JavaScript不仅支持数字、字符串和布尔值这些数据类型,还支持Number、String、Boolean类,这些类是基本数据类型的包装(wrapper)。
    例子:
    var s="some string";
    var len=s.length;
    这里,s保存了一个字符串,原始的字符串值是不会改变的。一个新的String对象被创建了,实现了对长度属性的访问,之后它就被销毁了。
    其它例子:
    var a="some string";
    var b=new String("some string");
    var c=["a","b","c"];
    var d=new Array("a","b","c");

    alert(typeof a);//string
    alert(a instanceof String);//false
    alert(a instanceof Object);//false

    alert(typeof b);//object
    alert(b instanceof String);//true
    alert(b instanceof Object);//true

    alert(typeof c);//object
    alert(c instanceof Array);//true
    alert(c instanceof Object);//true

    alert(typeof d);//object
    alert(d instanceof Array);//true
    alert(d instanceof Object);//true

    2)Function类型
    做为JavaScript的一种特殊类型,我们将看到函数在面向对象编程中起到了非常关键的作用。

    2.值和引用

    类型 复制 传递 比较
    数字
    布尔值
    字符串 不可变的 不可变的
    对象 引用 引用 引用
    函数 引用 引用 引用
    数组 引用 引用 引用

    例子:
    var s1="hello";
    var s2="hell"+"o";
    alert(s1==s2);//true

    var d1=new Date();
    var d2=new Date();
    alert(d1==d2);//false

    3.this
    在构造函数中,指代新创建的对象实例;
    在对象的方法被调用时,指代调用该方法的对象实例。

    4.arguments
    arguments属性由解释器创建,用于访问函数对象的每一个参数。

    5.callee,caller
    arguments的callee属性获取对正在执行的Function对象的引用;
    Function对象的caller属性获取正在调用当前函数的父函数对象。

    6.apply,call
    两者都是将函数绑定到其它对象上执行的,区别在于调用方式:
    apply([thisObj[,argArray]])
    call([thisObj[,arg1[,arg2[,[,.argN]]]]])

    7.匿名函数
    (function(a,b){
     return a+b;
     })(1,1);
    等价于:
    function f(a,b){
     return a+b;
    }
    f(1,1);

    8.null,undefined
    null是JavaScript的关键字,表示空值。可以看作Object类型的一个特殊值。
    undefined不是关键字,它是一个全局变量,使用了未定义变量、变量未赋值、void运算符,都会返回“undefined”。

    9.constructor
    从JavaScript1.1开始,每个对象都具有一个constructor属性,它引用的是用来初始化该对象的构造函数。

    10.prototype
    JavaScript1.1引入了原型对象的概念,每一个对象都有一个原型对象,对象可以继承它的原型对象的所有属性和方法。
    要为一个对象的类制定原型对象,需要将构造函数的prototype属性设置为指定的对象。之后,如果用构造函数初始化对象时,会自动将指定的对象作为新创建对象的原型对象。

    注意:
    1)使用原型对象可以减少每个继承对象的内存需求量;
    2)即使属性是在对象被创建后才加到它的原型对象中的,对象也能够继承这些后定义的属性。
    3)当调用一个对象的一个属性时,先在该对象定义内查找该属性,如果没有该属性才到该对象的原型对象中查找,依此类推。

    三、实现
    在面向对象编程中,我们可以把过程编程中的一个个function看作一个个独立定义的类,函数名即为类名。
    1.例子:Circle类
    function Circle(radius){
     //实例变量
     this.r=radius;
    }

    //静态变量
    Circle.PI=3.14159;

    //实例方法
    Circle.prototype.area=function(){
     return Circle.PI*this.r*this.r;
    }

    //静态方法
    Circle.max=function(a,b){
     if(a.r>=b.r){
      return a;
     }
     else{
      return b;
     }
    }

    //调用
    var a=new Circle(2);
    var b=new Circle(3);
    var c=a.area();
    var d=Circle.max(a,b);

    2.继承
    1)一种继承方式
    //这里我们将CircleMore类的prototype指向了一个Circle类实例,
    //并增加了circumference方法。
    function CircleMore(radius){
     this.r=radius;
    }

    CircleMore.prototype=new Circle(0);

    CircleMore.prototype.circumference=function(){
     return 2*Circle.PI*this.r;
    }

    这样能够实现对Circle的继承,但是这里存在一点问题:我们直接把CircleMore类的prototype指向了一个Circle类实例,这样就覆盖了JavaScript提供的原型对象,而且抛弃了给定的constructor属性,这样CircleMore的constructor属性就指向了父类Circle的constructor属性。而且这种方式总是使人感觉怪怪的。

    2)Ajax架构Prototype(区别前面提到的prototype哦)的继承方式

    //Prototype框架为Object对象定义了extend方法,
    //将source的属性和方法复制到了destination。
    Object.extend = function(destination, source) {
      for (var property in source)
        destination[property] = source[property];
      return destination;
    };

    //调用
    function ParentClass(){...}
    function SubClass(){}
    SubClass.prototype=Object.extend({
     newMethod:function(){
      alert("newMethod");
     }
    },
    ParentClass.prototype
    );

    3)如果这里对两个参数交换位置,则是对原对象的开展。
    例子:通过extend方法对String对象进行了扩展

    Object.extend(String.prototype,{
     newMethod:function(){
      alert("newMethod");
     }
    });

    3.多态

    Object.extend = function(destination, source) {
      for (var property in source)
        destination[property] = source[property];
      return destination;
    }

    //基类
    function base(){}
    base.prototype={
     initialize:function(){
      this.oninit();//调用了一个虚方法
     }
    }

    //子类SubClassA
    function SubClassA(){}
    SubClassA.prototype=Object.extend({
     //...其它属性方法
     prop:"SubClassA",
     oninit:function(){
      alert(this.prop);
     }},
     base.prototype
    }

    //子类SubClassB
    function SubClassB(){}
    SubClassB.prototype=Object.extend({
     //...其它属性方法
     prop:"SubClassB",
     oninit:function(){
      alert(this.prop);
     }},
     base.prototype
    }

    //调用
    var a=new SubClassA();
    var b=new SubClassB();

    a.initialize();//输出"SubClassA"
    b.initialize();//输出"SubClassB"

    四、JavaScript与设计模式

    1.Singleton

    function Singleton(){
     if(Singleton.caller!=Singleton.getInstance){
      throw new Error("Can not new Singleton instance!");
     }
     this.prop="some string";
     //...
    }

    Singleton._instance=null;

    Singleton.getInstance=function(){
     if(this._instance==null){
      this._instance=new Singleton();
     }
     return this._instance;
    }

    var a=Singleton.getInstance();
    var b=Singleton.getInstance();
    b.prop="another string";
    alert(a.prop);//"another string"
    alert(b.prop);//"another string"

    2.Factory

    function XMLHttpFactory(){}

    XMLHttpFactory.createXMLHttp=function(){
     if(...){
      return new XMLHttpRequest();
     }
     else if(...){
      return new ActiveXObject("MSXML2.XMLHttp");
     }
     ...
    }

    var xmlhttp=XMLHttpFactory.createXMLHttp();

    五、备注

    参考资料:
    《JavaScript权威指南(第三版)》 中国电力出版社
    《JavaScript高级程序设计与应用实例》 人民邮电出版社
     Prototype 1.6.0
     YUI 2.3.1

  • 相关阅读:
    main函数的一些特性
    确保函数的操作不超出数组实参的边界
    今天学习了一点sed
    libevent 与事件驱动
    mvc3 action验证失败后的自定义处理
    使用spring.net+nibernate时如何用aspnet_regiis加密数据库连接字符串
    C# 中 IList IEnumable 转换成 List类型
    Nhibernate 过长的字符串报错 dehydration property
    小论接口(interface)和抽象类(abstract class)的区别
    C# 语言在函数参数列表中出现this关键词的作用
  • 原文地址:https://www.cnblogs.com/meetrice/p/1223317.html
Copyright © 2020-2023  润新知