天天看点

js 中作用域、闭包的总结作用域的理解

前言:作用域是js中一个非常基础的知识,也是前端面试题喜欢考察的地方。同时理解作用域也是使用闭包的一个前提。

作用域的理解

1、首先要理解js中没有块级作用域,js只有全局作用域和函数作用域;

  • 没有在函数体里面声明的变量都是全局的
  • 没有使用var 声明的变量都是全局的

2、然后我们要明白:作用域查找时,是查找定义时的作用域,而不是运行时的作用域

var a=;
function fn(){
    var a=;
    console.log('fn',a);
}
console.log('global',a);//200
fn();//100
           

3、this的使用,this和作用域有着很大的不同:this指向的是调用时的对象,而不是定义时的对象;

var wang={
  name : "对象内部",
  fn : function fn(){
       console.log(this.name);
  }
};
wang.fn();//对象内部
//使用call改变其作用域,使this指向call里面的对象
wang.fn.call({name:"改变作用域"});
           

类似call的函数还要apply、bind

apply的用法和call差不多,这里介绍一下bind的用法

var fn2=function(name){
   alert(name);
   console.log(this);
}.bind({y:});  //bind(obj)这个方法,将this转变为指向obj 即this=obj
fn2('zhangsan');
           

4、现在了解上面的知识之后,我们开始讲闭包;

闭包:就是一个函数内部的那个函数,可以在外部用来访问函数内部数据,防止数据被污染(阮一峰的解释为:闭包就是能够读取其他函数内部变量的函数。)

eg:写一个函数判断数据是否是第一次出现

function isFirstLoad() {
     var _list=[];//将数组定义在内部,可以有效的避免数据的污染
     return function(id){
        if(_list.indexOf(id) === -){
           _list.push(id);
           console.log(_list);
           return true;
        }else{
           return false;
        }
     }
  }
  var FirstLoad=isFirstLoad();
  console.log(FirstLoad());//true
  console.log(FirstLoad());//false
  console.log(FirstLoad());//true
  console.log(FirstLoad());//fasle
           

理解闭包之后,我们再讲闭包的使用场景

  • 作为函数返回
function F1(){
    var a=;
    return function(){
        console.log(a);
    }
}
var f1=F1()
var a=;
f1();//100
           
  • 作为函数传参
function F1(){
    var a=;
    return function(){
        console.log(a);
    }
}
var f1=F1()
function F2(fn){
    var a=;
    fn();
}
F2(f1)//100
           

继续阅读