概览:
一:原型与原型链
二:闭包
一:原型与原型链
 { // 构造函数声明
this.age = 20;
}
// 构造函数原型对象上添加属性 weight
Dog.prototype.weight = 20;
// 创建对象实例
var m = new Dog();
</script>
总结:
1.
2.隐式原型
null是没有__proto__的
3.显式原型(包括构造函数也有prototype的属性)
4.
Function除外,因为他指向
5.
6.
7.Object是构造函数,也是对象。Object的prototype是所有对象的根。
8.Function是函数对象的构造函数。Function的原型对象是所有函数的根。而它的内部原型是Object的原型对象,这就是关键点了。
二:闭包
定义:由于函数嵌套调用的时候,如果内部函数访问外部函数的变量。
闭包代码的特点
代码特点:
1、函数b嵌套在函数a内部;
2、函数a返回函数b。
3.函数b中使用了函数a里面的变量
示例:
<script>
function foo(x) {
return function (y) {
console.log(x + y + (++tmp));
};
}
// 调用foo方法执行。并把返回的函数给了 bar变量。
var bar = foo(2); // 此时bar指向了 匿名函数。bar是一个闭包:函数 + x tmp
bar(10);
bar(20);
<script>
闭包的应用
1.匿名自执行函数模拟块级作用域
(function(){
// 块级作用域环境
})();
;(function(a) {
var m = 9;
//
console.log(a);
})(8);
(function(){
// 模拟块级作用域
})();
2.循环注册dom事件中的index
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
</ul>
<script>
var lis = document.querySelectorAll('li');
console.log(lis);
// // 循环注册事件的index的典型错误。
for(var i = 0; i < lis.length; i++) {
lis[i].onclick = function(e) { //事件的方法执行是:当事件触发的时候执行。
// 变量i是父函数里面的变量。
console.log(i); // 5个5把当前的索引i的值打印出来。
};
}
改正:
// 把循环注册事件做成 自执行函数来传递变量i。
for(var i = 0; i < lis.length; i++) {
(function(a) {
lis[a].onclick = function(e) {
console.log(a);
};
})(i); // 传参数:是做的值的复制,做的副本。点击会出来0 1 2 3 4
}
<script>
3.setTimeOut中的闭包应用
典型的错误
for(var i = 0 ; i < 10; i++) {
setTimeout(function(){
console.log(i);//10个10
},1000);
}
改正:
// 用匿名自执行函数解决
for(var i = 0; i < 10; i++) {
(function(a){
setTimeout(function() { // 注册1秒后的代码执行很快。
console.log(a); // 函数体是在1秒后才执行。打印出来0~9
}, 1000);
})(i);
}
闭包的优缺点:
1.保护函数内的变量安全,加强了封装性
2.在内存中维持一个变量(用的太多就变成了缺点,占内存)