1. 程式人生 > >JavaScript基礎知識——作用域和閉包

JavaScript基礎知識——作用域和閉包

rev return else 演示 場景 如何 存在 構造函數 click

作用域和閉包

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)

JavaScript基礎知識——作用域和閉包