图3.3
上图代码运行结果为:先弹出“btn1”,然后弹出“btn2”,最后弹出“content ”。它与前一个代码的区别是,一个是绑定,一个是注册。即DOM元素只能绑定一个事件,类似变量,后面的会把前面的覆盖掉;但是DOM元素可以注册多个事件,即在注册第一个事件的时候,同时注册了第二个事件,所以在执行的时候,会从第二个(也就是当前元素的最后一个注册事件)开始执行,直到执行完第三个事件。
四. 闭包
闭包,官方对闭包的解释是:一个拥有许多变量和绑定了这些变量的环境的表达式(通常是一个函数)。因而,这些变量也是该表达式的一部分。闭包的特点如下:
作为一个函数变量的一个引用,当函数返回时,其处于激活状态。
2. 一个闭包就是当一个函数返回时,一个没有释放资源的栈区。
简单的说,Javascript允许使用内部函数,即函数定义和函数表达式位于另一个函数的函数体内。而且,这些内部函数可以访问它们所在的外部函数中声明的所有局部变量、参数和声明的其他内部函数。当其中一个这样的内部函数在包含它们的外部函数之外被调用时,就会形成闭包。
图4.1
如上图所示,给函数原型增加一个方法,同时创建一个实例,会得到结果3.14159。
图4.2
上图就是把一个函数return为一个变量,那么当创建该函数的实例的时候,所有该变量具有的方法都可以被调用,同时还是在函数作用域之外被调用,即闭包,结果依旧为3.14159。
图4.3
这属于最容易理解的方式,即直接new一个对象,给它赋予各种属性和方法,最终结果依旧为3.14159。
图4.4
这种方式是使用最多的一种方式,也是最方便的一种方式。(var obj = {}就是声明一个空的对象。)
闭包的用途如下:
函数只需要执行一次,其内部变量无需维护,比如UI的初始化;
前端缓存。假设有一个很耗性能和时间的函数对象,每次调用都需要很久的时间,那么我们就需要将计算出来的值存储起来,当调用这个函数的时候,首先在缓存中查找,如果找不到,则进行计算,然后更新缓存并返回值,如果找到了,直接返回查找到的值即可。闭包正是可以做到这一点,因为它不会释放外部的引用,从而函数内部的值可以得以保留。
封装函数(组件化)
实现类和继承(参考第一种写法)
五. call与apply
共同点
都“可以用来代替另一个对象调用一个方法,将一个函数的对象上下文从初始的上下文改变为由thisObj指定的新对象”。
不同点
apply:apply(thisObj,[argArray])。最多只能有两个参数——新this对象和一个数组argArray。如果给该方法传递多个参数,则把参数都写进这个数组里面,当然,即使只有一个参数,也要写进数组里。如果argArray不是一个有效的数组或arguments对象,那么将导致一个TypeError。如果没有提供argArray和thisObj任何一个参数,那么Global对象将被用作thisObj,并且无法被传递任何参数。