彩世界平台-彩世界时时app-彩世界开奖app苹果下载

热门关键词: 彩世界平台,彩世界时时app,彩世界开奖app苹果下载

您的位置:彩世界平台 > 新闻动态 > JavaScript之使用JavaScript模仿oop编程

JavaScript之使用JavaScript模仿oop编程

发布时间:2019-09-03 21:50编辑:新闻动态浏览(122)

    JavaScript是互联网时代编程语言的霸主,统领浏览器至今已有许多年头,而这股风潮很可能随着HTML 5的兴起而愈演愈烈。如今JavaScript更是在Node.js的帮助下进军服务器编程领域。“单线程”和“无阻塞”是JavaScript的天性,因此任何需要“耗时”的操作,例如等待、网络通信、磁盘IO都只能提供“异步”的编程接口。尽管这对服务器的伸缩性和客户端的响应能力都大有脾益,但是异步接口在使用上要比传统的线性编程困难许多,因此也诞生了如jQuery Deferred这样的辅助类库。Jscex的主要目的也是简化异步编程,但它使用了一种与传统辅助类库截然不同的方式,尽可能地将异步编程体验带领到新的高度。

    第一,

    开放平台之实践——来自百度、360、腾讯、盛大的案例分享JavaScript编程几乎总是伴随着异步操作,传统的异步操作会在操作完成之后,使用回调函数传回结果,而回调函数中则包含了后续的工作。这也是造成异步编程困难的主要原因:我们一直习惯于“线性”地编写代码逻辑,但是大量异步操作所带来的回调函数,会把我们的算法分解地支离破碎。此时我们不能用if来实现逻辑分支,也不能用while/for/do来实现循环,更不用提异步操作之间的组合、错误处理以及取消操作了。

    首先,使用关键字function定义一个类

    快速入门:排序动画

    function Shape1(ax,ay) {//此时将function看成声明类的标志
        var x=0;
        var y=0;
        var  init=function () {//构造函数   对内部的变量赋值
            x=ax;
            y=ay;
        }
    init();//构造函数的调用
         this.getX=function () {//this声明公有函数   var 声明私有   get方法
          return x;
        }
    }
    

    我们先来看一个简单的例子。“冒泡排序”是最常见的排序算法之一,它的JavaScript实现如下:

    然后,对象的实例化+调用

    var compare = function (x, y) {      return x - y;  }   var swap = function (array, i, j) {      var t = array[i];      array[i] = array[j];      array[j] = t;  }   var bubbleSort = function (array) {      for (var i = 0; i < array.length; i++) {          for (var j = 0; j < array.length - i; j++) {              if (compare(array[j], array[j + 1]) > 0) {                  swap(array, j, j + 1);              }          }      }  } 
    
    var shape=new Shape1(1,2);//实例化
    alert(shape.getX());//公有方法的调用
    

    由于某些原因——例如教学所需,我们希望能够通过动画来直观地感受不同排序算法之间的差异。将一个排序算法改写为动画效果的“基本策略”十分简单:

    第二,

    ◆ 在每次元素“交换”和“比较”操作时暂停一小会儿(因为它们是排序算法的主要耗时所在)。

    静态属性和静态方法
    
    js中静态方法是作用在类身上的而非对象上
    一,对于使用function声明的类
    

    ◆ 在元素“交换”过后重绘图像。

    (1)首先,先定义一个类

    只需增加这样两个“简单”的功能,便可以形成算法的动画效果。但实际上,实现这个策略并没有听上去那么容易。在其它许多语言或是运行环境中,我们可以使用sleep方法来暂停当前线程。这对代码的逻辑结构的影响极小。但是在JavaScript中,我们只有setTimeout可以做到“延迟”执行某个操作。setTimeout需要与回调函数配合使用,但这会严重破坏算法的逻辑结构,例如,我们再也无法使用for来实现哪怕是最最简单的循环操作了。因此,排序算法的动画似乎只能这么写:

    function Person() {this.Name="小李"};
    
    // 异步操作签名约定:  // function (arg1, arg2, ..., callback) {  //     异步操作完成后使用callback回传结果  // }   var compareAsync = function (x, y, callback) {      // 延迟10毫秒返回结果      setTimeout(10, function () {          callback(x - y);      });  }   var swapAsync = function (a, i, j, callback) {      // 交换元素      var t = a[i]; a[i] = a[j]; a[j] = t;      // 重绘      repaint(a);      // 延迟20毫秒才返回      setTimeout(20, callback);  }   // 外部循环,从下标为i的元素开始处理  var outerLoopAsync = function (array, i, callback) {      // 如果i还在数组长度范围内      if (i < array.length) {          // 则进入内部循环,与下标为i的元素进行比较          innerLoopAsync(array, i, 0, function () {              // 内部循环结束以后,在外部循环中处理i的下一个元素              outerLoopAsync(array, i + 1, callback);          });      } else {          // i超出数组长度,表示外层循环结束          callback();      }  }   // 内部循环,从下标j开始,与下标为i的元素进行比较  var innerLoopAsync = function (array, i, j, callback) {      // 如果j在合适范围内      if (j < array.length - i) {          // 则比较下标j及其相邻元素          compareAsync(array[j], array[j + 1], function (r) {              // 如果次序不对              if (r > 0) {                  // 则交换及其相邻元素                  swapAsync(array, j, j + 1, function () {                      // 交换之后,则重复内层循环比较下标j的下一个元a素                      innerLoopAsync(array, i, j + 1, callback);                  });              } else {                  // 假如次序已经正确·,则直接重复内存循环比较下标j的下一个元a素                  innerLoopAsync(array, i, j + 1, callback);              }          });      } else {          // j已经超出范围,一个元素已经处于合适的位置,内层循环结束          callback();      }  }   // 冒泡排序主方法  var bubbleSortAsync = function (array, callback) {      // 从第一个元素开始执行外部循环,      // 外部循环结束则意味着排序完毕      outerLoop(array, 0, callback || function () { });  }   // 调用  var array = ...; // 初始化数组  bubbleSortAsync(array); 
    

    (2)然后,为类添加静态变量 静态方法

    相信您也可以看得出来,如果使用传统回调的方式来实现一个冒泡排序动画会有多么麻烦。而“支离破碎”所导致的更严重的问题,是代码“语义”方面的损失。例如,新来一位开发人员想要维护这段代码,他能够看出上面这段代码是“冒泡排序”吗?如果您给出“冒泡排序”的动画,又能轻易地将算法“说明”给别人理解吗?如果需要简单补充一些功能,又该将新代码添加在何处?使用传统线性编程的优势之一,在于容易快速编写出逻辑清晰而“内聚”的实现,即使需要补充一些功能,则可以通过局部变量将状态修改控制至极小。我们几乎可以这么说,基于回调函数的异步编程,让许多传统程序设计中总结出来的实践与模式付诸东流。

      Person.age=0;
        Person.ShowName=function (obj) {
            console.log(obj.Name)//此时的Name是Person对象类下面全局变量,需要Person对象方可访问
        };
    

    不过有了Jscex以后世界便大不一样了,它将编程体验变得“如初见般美好”:

    (3)调用

    // 异步的比较操作   var compareAsync = eval(Jscex.compile("async", function (x, y) {      $await(Jscex.Async.sleep(10)); // 等待10毫秒      return x - y;  }));   // 异步的交换操作  var swapAsync = eval(Jscex.compile("async", function (array, i, j) {      var t = array[i];      array[i] = array[j];      array[j] = t;       repaint(array); // 重绘       $await(Jscex.Async.sleep(20)); // 等待20毫秒  }));   // 异步的冒泡排序   var bubbleSortAsync = eval(Jscex.compile("async", function (array) {      for (var i = 0; i < array.length; i++) {          for (var j = 0; j < array.length - i; j++) {              // 执行异步的比较操作              var r = $await(compareAsync(array[j], array[j + 1]));              if (r > 0) {                  // 执行异步的交换操作                  $await(swapAsync(array, j, j + 1));              }          }      }  }));   // 调用  var array = ...; // 初始化数组  bubbleSortAsync(array).start(); 
    
     Person.ShowName(new Person());
    

    以上这段代码几乎不用做任何解释,因为它完全便是在标准的“冒泡排序”算法之上,增加了之前所提到的“基本策略”。这便是Jscex改进异步编程体验的手段:程序员编写最自然的代码,并使用$await来执行其中的异步操作。Jscex提供的编译器(即compile方法)会将一个普通的JavaScript函数编译为“回调函数”组织起来的异步实现,做到“线性编码,异步执行”的效果。

     

    您可以在此观察冒泡排序的动画效果(需要IE9,Chrome,Firefox等支持Canvas的浏览器)。这张页面里还实现了选择排序和快速排序算法的动画,都是基于Jscex的优雅实现。如果您感兴趣,也可以使用传统的、基于回调的方式来编写这些算法动画,然后跟页面中的代码实现进行对比,便可以更好地了解Jscex的优势。

    总结:先有类,再添加有静态成员,
    
    Person是一个类 可以实例化,下面有静态成员需要实例化.才能访问
    
    二,没有function声明的类(对象)--简单类
    (1),先有一个类
    
    var a={};//一个类
    

    使用Jscex开发异步程序

    (2)为类添加属性

    Jscex可以在任何支持JavaScript(ECMAScript 3)的运行环境里执行,例如,包括IE 6在内的现代浏览器,服务器端的Node.js,以及如Rhino一样的JavaScript引擎等等,它们的区别仅仅在于“引入Jscex脚本文件”的方式不同而已。Jscex模块化十分细致,在使用时需要引入不少文件,部分原因也是由于JavaScript环境至今还缺少一个包管理机制所造成的:

    a["name"]="1";//添加属性
    

    ◆ lib/json2.js:由Douglas Crockfod编写的JSON生成器,对于原生不支持JSON.stringify方法的JavaScript环境(例如早期版本的IE),则需要引入该文件。

    (3)调用

    ◆ lib/uglifyjs-parser.js:UglifyJS项目(jQuery项目官方使用的压缩工具)所使用的的JavaScript解析器,这是LISP项目parse-js的 JavaScript 移植,它负责Jscex中的语法解析工作。

    alert(a.name);
    

    ◆ src/jscex.js:JIT编译器实现,负责在运行时生成代码。这也是Jscex.compile方法的具体实现所在。

     

    以上三个文件构成了Jscex的编译器核心,它们只需在开发环境中使用(例如在页面引用它们),目的只是为了提供近乎原生JavaScript的开发体验。对于Jscex来说,它的首要原则(没有之一)便是“保证JavaScript程序员的传统开发体验”。而对于开发和生产环境都必不可少的只有以下两个文件:

    ◆ src/jscex.builderBase.js:Jscex中“构造器”的公用部分。

    ◆ src/jscex.async.js:Jscex的“异步构造器”,用于支持异步程序开发。

    这两个文件在精简和gzip之后,只有3KB左右大小,几乎不会给应用程序带来什么影响。

    本文由彩世界平台发布于新闻动态,转载请注明出处:JavaScript之使用JavaScript模仿oop编程

    关键词:

上一篇:使用node.js进行服务器端JavaScript编程(1)

下一篇:没有了