返回顶部

javascript中五种方式去执行一个任务

来源:无 发布时间:2016-03-13

最近看了《javascript设计模式》,感觉书中对javascript这门编程语言的灵活性的描述非常到位,有些地方虽然自己在开发过程已经用到过,但为了加深记忆和理解,在此对js如何编写一个执行任务的代码作一个例子记录。此例子涵盖js创建函数、过程式编程、面向对象式编程、链式编程等方面的内容!

例子的模型

我们的需求是有一个高宽都为100px、背景颜色为红色的div,其id值为dom1,我们需要它向右移动缓慢移动200px,持续时间为2秒。以下是它的html内容,可复制粘帖查看效果。

<div id="dom1" style="width:100px;height:100px;position:relative;left:0px;top:0px;background-color:#c00;">
</div>

方式一:过程式编程

我们可以创建两个函数,从上到下写,总之根据需求来写,你可以想到那里就写到那里!

首先我们需要一个函数来启动动画,然后需要一个函数来停止动画,以下是源代码!可复制粘帖查看效果!

<script type="text/javascript" >
var dom = document.getElementById("dom1");
var pos = 0;
var clearIntervalId = null; //定义一个函数启动动画,并循环调用自己
function startAnimation(instance,maxInstance){
pos += instance;
dom.style.left = pos + 'px';
if(pos>maxInstance){
pos = maxInstance;
dom.style.left = pos + 'px';
clearInterval(clearIntervalId);

};

};
//每毫秒移动的距离等于路程除以时间
var instance = 200/2000;
clearIntervalId = setInterval("startAnimation(instance,200)",1);
</script>
这里我发现一个问题,我本意是用两秒的时间移动200px,可是最终效果却是花了很长时间才移动到200px的位置上!应该跟setInterval机制的延迟有问题,这里先记录下来,我到时候把解决方法写出来,不过在这里不影响我们要讨论的问题!另外可以通过css3实现正确的效果!

从这里,我们可以看出js过程式编程,要在函数外定义许多变量,这无疑在大型项目中是很危险的,因为你定义了很多外部变量,到时候命名冲突是一个大问题。并且过程式编程复用起来较困难!

方式二:面向对象式编程

面向过程转换到面向对像式编程,首先要明白的一点就是,把原来过程式编程需要的函数用对象的方法来保存,原来过程式编程的全局变量用对象的属性来保存,调用函数对应的是调用对象的方法,引用全局变量对应的是引用对象的属性!好,这里不多说了,下面我们直接来看用函数编程怎么实现上面的动画效果!代码如下

<script type="text/javascript" >
//构造函数
function Anim(id){
//保存对象的引用
var _that = this; this.dom = (typeof id === "string")?document.getElementById(id):id; //dom最开始的定位
this.pos = 0;
//动画的速度 路程/时间
this.speed = 200/2000; //定时器返回的id值
this.clearIntervalId = setInterval(function(){
_that.startAni();
},1);
}
Anim.prototype.startAni = function(){
//保存对象的引用
var _that = this;
this.pos += this.speed;
this.dom.style.left = this.pos+'px';
if(this.pos>200){
this.pos = 200; this.dom.style.left = 200 + 'px';
clearInterval(this.clearIntervalId);
return;

};
};
//最后一步 需要实例化一下对象
var animation = new Anim("dom1")

</script>

从这里我们可以看出,面向对象式编程对外只暴露一个变量,这样减少了全局变量对全局空间的污染。而且还可以看出很多过程式编程中的函数和变量对应的变成 了对象的方法和属性,这有一个很大的好处就是可以保存状态了,也可以保存私有变量了。并且我们还可以看出对象式编程的复用率是很好的,我在需要用的地方只需要new一个实例就好了!

方式三:原型式编程

其实这里跟第二种差不多的,不过并不像第二种那样单独为每一个属性或方法写在原型上,而是直接把构造函数的原型指定为一个对象,我们这里比如在第二个举的例子那里,那个Anim对象有很多方法的话,如果你每次都单独为每个方法开一个原型,我觉得代码量是很多的!比如下面你代码:

function Anim(id){
//代码省略
}
Anim.prototype.fun1 = function(){
//代码省略
}
Anim.prototype.fun2 = function(){
//代码省略
}
Anim.prototype.fun3 = function(){
//代码省略
}
//后面还有很多

像上面那样, 你得写很多了!其实我们可以这样,把上面的改变如下:

function Anim(id){
//代码省略
}
//直接把构造函数的原型指定为一个对象
Anim.prototype = {
fun1 : function(){//省略},
fun2 : function(){//省略},
fun3 : function(){//省略},
//还有很多
}

这样写起来是不是简练的多呢!

方式四:在Function的原型上添加方法

这种方法的思想主要是在Function的原型上添加一个方法,如下代码:

Function.prototype.method = function(name,fun){
this.prototype[name] = fun;
};