前言:作用域是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