天天看點

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
           

繼續閱讀