事件绑定后,检测顺序就会从被绑定的DOM下滑到触发的元素,再冒泡到绑定的DOM上,也就是说,如果你监听了一个DOM节点,那就等于你监听了其所有的后代节点。
代理的意思就是之间厅父节点的时间触发,以来代理对其后代节点的监听,而你需要做的只是通过currentTarget 属性得到触发元素并作出回应。
使用事件代理意味着你可以节省大量重复的事件监听,以减少浏览器资源消耗。还有一个好处就是让HTL独立起来,比如之后还有要加子元素的需求,也不需要再为其单独加时间监听了
常用的属性与方法:
javascript语言的特殊之处,就在于函数内部可以直接访问全局变量。另一方面,在函数外部自然无法读取函数内的局部变量。但是通过闭包,可以再函数外面访问到内部的变量 比如:
function num(){
var a = 1
function addNum(){
console.log(a) //1
}
}
函数addNum被包裹在函数num内部,这时num内部的所有局部变量,对addNum都是可见的。这就是Javascript语言特有的”链式作用域”结构(chain scope),子对象会一级一级地向上寻找所有父对象的变量。所以,父对象的所有变量,对子对象都是可见的,反之则不成立。
闭包允许将函数与其所操作的某些数据(环境)关连起来。这显然类似于面向对象编程。在面对象编程中,对象允许我们将某些数据(对象的属性)与一个或者多个方法相关联。因而,一般说来,可以使用只有一个方法的对象的地方,都可以使用闭包。
我们在举个栗子:
function num(){
var a = 100
function addNum(){
console.log(a++)
}
return addNum
}
var result = num()
result() //100
result() //101
原因:num() 是 addNum() 的父函数,而addNum() 被赋给了一个全局变量,这导致addNum始终存在内存中,而addNum的存在依赖于num,因此num也始终在内存中,一个牵着一个,不会在调用结束后,被垃圾回收机制回收
JavaScript 并不提供原生的支持,但是可以使用闭包模拟私有方法。私有方法不仅仅有利于限制对代码的访问:还提供了管理全局命名空间的强大能力,避免非核心的方法弄乱了代码的公共接口部分。
下面的示例展现了如何使用闭包来定义公共函数,且其可以访问私有函数和变量。这个方式也称为 模块模式(module pattern):
var Counter = (function() {
var privateCounter = 0
function changeBy(val){
privateCounter += val
}
return {
increment:function(){
changeBy(1)
}
decrement:function(){
changeBy(-1)
}
value:function(){
return privateCounter
}
}
})
console.log(Counter.value()) //0
Counter.increment()
Counter.increment()
console.log(Counter.value()) //2
Counter.decrement()
console.log(Counter.value()) //1
function showHelp(help){
document.getElementById('help').innerHTML = help
}
function makeHelpCallback(help){
return function(){
showHelp(help)
}
}
function setupHelp(){
var helpText = [
{'id': 'email', 'help': 'Your e-mail address'},
{'id': 'name', 'help': 'Your full name'},
{'id': 'age', 'help': 'Your age (you must be over 16)'}
]
for(var i = 0; i < helpText.length; i++){
var item = helpText[i]
document.getElementById(item.id).onfocus = makeHelpCallback(item.help)
}
}
在javascript中,每个函数都有一个原型属性prototype指向函数自身的原型,而由这个函数创建的对象也有一个proto属性指向这个原型,而函数的原型是一个对象,所以这个对象也会有一个proto指向自己的原型,这样逐层深入到Object对象的原型(null),这样就形成了原型链
一、通过Calculator 对象的prototype属性复制对象字面量来设定Calculator对象的原型
var Calculator = function (decimalDigits, tax) {
this.decimalDigits = decimalDigits;
this.tax = tax;
};
Calculator.prototype = {
add: function (x, y) {
return x + y;
},
subtract: function (x, y) {
return x - y;
}
};
//alert((new Calculator()).add(1, 3));
二、分别设置原型对象:
var Calculator = function(decimalDigits, tax) {
this.decimalDigits = decimalDigits
this.tax = tax
}
Calculator.prototype.add = function (x, y) {
return x + y;
}
Calculator.prototype.subtract = function (x, y) {
return x - y;
}
三、赋值原型prototype的时候使用function立即执行的表达式来赋值,即如下格式:Calculator.prototype = function () { } ();, 可以封装私有的function,通过return的形式暴露出简单的使用名称,以达到public/private的效果。
Calculator.prototype = function () {
add = function (x, y) {
return x + y;
},
subtract = function (x, y) {
return x - y;
}
return {
add: add,
subtract: subtract
}
} ();
1.CommonJS
CommonJS就是为JS的表现来制定规范,因为js没有模块的功能所以CommonJS应运而生,它希望js可以在任何地方运行,不只是浏览器中。
require()用来引入外部模块;exports对象用于导出当前模块的方法或变量,唯一的导出口;module对象就代表模块本身。
//out.js
exports.test = function(){
....
}
//in.js
var math = require('test')
exports.add = function(n) {
return math.test(val,n)
}
node.js 就是遵从common.js规范的
为什么说common.js不适合前端呢?是因为common.js是同步加载,而代码需要从一个服务器端分发到多个客户端执行,加载需要通过网络,这就不可避免的产生延迟,从而同步加载会大大降低网站的性能。所以,AMD应运而生。
2.AMD
AMD就只有一个接口:define(id?,dependencies?,factory);
它要在声明模块的时候制定所有的依赖(dep),并且还要当做形参传到factory中,像这样:
define(['dep1','dep2'], function(dep1,dep2){...})
define(function(){
var exports = {}
exports.method = function(){...}
return exports;
})
RequireJS就是实现了AMD规范了的
3.CMD
大名远扬的玉伯写了seajs,就是遵循他提出的CMD规范,与AMD蛮相近的,不过用起来感觉更加方便些,最重要的是中文版,应有尽有:cmd官网
define(function(require,exports,module){...})
CMD与AMD的不同之处: