JavaScript基础知识——作用域和闭包
作用域和闭包
Q: 1.说一下对变量提升的理解
2.说明this几种不同的使用场景
3.创建10个<a>
标签,点击时弹出对应序号
var i; for(i = 0; i < 10; i++){ (function(i){ var a = document.createElement('a'); a.innerHTML = i + '<br>'; a.addEventListener('click', function(e){ e.preventDefault(); alert(i); }); document.body.appendChild(a) })(i) }
4.如何理解作用域
5.实际开发中闭包的应用
// 闭包实际应用中主要用于封装变量,收敛权限 function isFirstLoad() { var _list = []; return function ( id ) { if ( _list.indexOf( id ) >=0 ) { return false; } else { _list.push( id ); return true } } } //使用 var firstLoad = isFirstLoad(); firstLoad(10); // true firstLoad(10); // false firstLoad(20); // true
(1)、执行上下文
范围:一段<script>或者一个函数
全局:变量定义、函数声明
函数:变量定义、函数声明、this、arguments
声明提前
// 一下写法不推荐,只是演示声明提前
console.log(a);//undefined var a = 100; fn('张三');// 张三 20 function fn(name){ age = 20, console.log(name,age); var age }
(2)、this
this要在执行师才能确认,定义是无法确认
1 var a = { 2 name:'A', 3 fn:function(){ 4 console.log(this.name); 5 } 6 }; 7 a.fn(); //this===a 8 a.fn.call({name:'B'}); //this==={name:'B'} 9 var fn1 = a.fn; 10 fn1(); //this===Window
this在不同情况下的指代对象不同
a、作为构造函数执行
function Foo (name) { this.name = name; console.log() } var f = new Foo('xiaoming'); f();//
b、作为对象属性执行
var obj = { name: 'A', printName: function(){ console.log(this.name) } } obj.printName();//this==>obj
c、作为普通函数执行
function fn(){ console.log(this) } fn();//this===>window
d、call、apply、bind
function fn1(name){ alert(name) console.log(this); } fn1.call({x:100},'小明');// 此时this指代的就是 {x:100}
(3)、作用域
JavaScript没有块级作用域
if (true) { var name = '小明'; } console.log(name);//小明
函数和全局作用域
// 函数和全局作用域 var a = 100; function fn () { var a = 200; console.log('fn', a); } console.log('global', a);//100 fn();//200
(4)、作用域链
// 函数和全局作用域 var a = 100; function fn () { var b = 200; // 当前作用域没有定义的变量,自由变量 console.log( a ); console.log( b ) } fn();
var a=100 function F1(){ var b=200 function F2(){ var c=300 console.log(a) //a是自由变量,在F2中未找到便向父级作用域F1查找,仍未找到,继续向上查找,在Window中找到 console.log(b) //b是自由变量 console.log(c) } F2() } F1() //100 200 300
调用在当前作用域不存在的变量,便会向父级作用域查找。需要注意的是,父级作用域是函数定义时产生的,并非函数调用时
(5)、闭包
function F1(){ var a = 100; return function(){ console.log(a);// 自由变量,父作用域寻找 } } var f = F1(); var a = 200; f();//100
(1)函数作为返回值
function F1(){ var a = 100; return function(){ console.log(a);// 自由变量,父作用域寻找 } } var f = F1();
(2)函数作为参数来传递
function F2(fn) { var a = 200; fn() } F2(f1)