对象原型链
1.js中所有对象都具有__proto__属性指向它的原型,普通对象的原型是Object,Object的原型是null
2.只有function对象还额外具有一个prototype属性
当这个function作为构造函数new了一个对象之后,这个function的prototype即作为该对象的___proto__属性
立即执行函数
方式1
(function (){
alert("1");
})();
方式1.1
+function (){
alert("1");
}();
//也可以将+换成 !、+、-、~中任何的一个
方式2
(function (){
alert("1");
}());
立即执行函数最本质的作用是:创建一个独立的作用域。
可以解决for循环绑定事件时i的问题
var liList = document.getElementsByTagName('li');
for (var i = 0; i < 6; i++) {
(function (i) {
liList[i].onclick = function () {
alert(i); // 0、1、2、3、4、5
}
})(i);
}
闭包(案例取自mozilla官网)
闭包允许将函数与其所操作的某些数据(环境)关联起来。这显然类似于面向对象编程。在面向对象编程中,对象允许我们将某些数据(对象的属性)与一个或者多个方法相关联。
function makeAdder(x) {
return function(y) {
return x + y;
};
}
var add5 = makeAdder(5);
var add10 = makeAdder(10);
console.log(add5(2)); // 7
console.log(add10(2)); // 12
makeAdder相当于一个函数工厂,每一个制造出来的函数与x绑定,因此就可以解决for循环绑定事件的问题
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);
}
}
setupHelp();
//所有的回调不再共享同一个环境, makeHelpCallback 函数为每一个回调创建一个新的词法环境。在这些环境中,help 指向 helpText 数组中对应的字符串。
采用匿名闭包的解决方法
function showHelp(help) {
document.getElementById('help').innerHTML = 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++) {
(function() {
var item = helpText[i];
document.getElementById(item.id).onfocus = function() {
showHelp(item.help);
}
})(); // 马上把当前循环项的item与事件回调相关联起来
}
}
setupHelp();
如果不是某些特定任务需要使用闭包,在其它函数中创建函数是不明智的,因为闭包在处理速度和内存消耗方面对脚本性能具有负面影响。