JS零碎知識(shí)點(diǎn)總結(jié)(2)

1、遞歸 (arguments.callee)

遞歸函數(shù)是在一個(gè)函數(shù)通過(guò)名字調(diào)用自身的情況下構(gòu)成的

function  factorial (num) {
    if ( num <= 1 ) {
       return 1;
    } else {
       return arguments.callee(num - 1);
    }
}

嚴(yán)格模式下,js直接調(diào)用argumengs.callee會(huì)報(bào)錯(cuò),所有可以使用命名函數(shù)表達(dá)式來(lái)替代

var  factorial = ( function f (num) () {
  if ( num < 1) {
    return num;
  } else {
  return num * f (num-1)
  }
})

2、閉包

利用內(nèi)部函數(shù)可以訪(fǎng)問(wèn)外部函數(shù)變量這個(gè)特點(diǎn)來(lái)實(shí)現(xiàn)
創(chuàng)建閉包的常用方式:在一個(gè)函數(shù)內(nèi)創(chuàng)建另一個(gè)函數(shù)(一般會(huì)使用return暴露出來(lái))

function out (variable) {
  retutn in (object) {
    var val = object[variable];
    alert(val );
  }
}

一般來(lái)說(shuō),當(dāng)函數(shù)執(zhí)行完成后,自己所占用的內(nèi)存會(huì)被銷(xiāo)毀釋放,內(nèi)存中僅保存全局作用域(全局執(zhí)行環(huán)境的變量對(duì)象,其實(shí)就是全局變量),如果外部有引用對(duì)象引用了內(nèi)部實(shí)現(xiàn)閉包的匿名函數(shù)的話(huà),則匿名執(zhí)行完成也不會(huì)被銷(xiāo)毀,因?yàn)橥獠康囊脤?duì)象未被銷(xiāo)毀,所以要銷(xiāo)毀的話(huà)可以設(shè)置外部引用為null。

var k = out("name");
var r = k({name:"ding"},{name:"liang"});
k = null;

2.1 閉包與變量

作用域鏈機(jī)制導(dǎo)致:閉包只會(huì)獲取包含函數(shù)中變量的最后的一個(gè)值

function () {
  var r = new Array();
  for (var i = 0;i<10;i++) {
    r[i] = function(i) {
        return i;
    }
  }
return r;
}
// 結(jié)果[scope]內(nèi)的值都為10;
// 通過(guò)閉包內(nèi)再嵌套一層閉包避免
function () {
  var r = new Array();
  for (var i = 0;i<10;i++) {
    r[i] = function(num) {//標(biāo)志2
        return function(){
          return num;
        };
    }(i); //標(biāo)志1
  }
return r;
}
//標(biāo)志1,這種寫(xiě)法其實(shí)就是直接馬上執(zhí)行,這個(gè)創(chuàng)建的對(duì)象字面量的匿名函數(shù)(標(biāo)志2),同時(shí)傳參數(shù)i。

2.2 this對(duì)象

this對(duì)象是在運(yùn)行時(shí)基于函數(shù)的執(zhí)行環(huán)境而綁定的
全局對(duì)象的話(huà):this指向window;
函數(shù)被對(duì)象方法調(diào)用的話(huà):this指向這個(gè)函數(shù)

var name = "this window";
var ding = {
  name = "this ding"
  getName = function () {
      return this.name;
  }
}
alert(this.name); //this window
alert(ding .getName ()); //this ding

//如果this在閉包內(nèi)的話(huà),會(huì)指向window
var name = "this window";
var ding = {
  name = "this ding"
  getName = function () {
    return function () {
      return this.name;
    }
  }
}
alert(ding .getName ()()); //this window
//解決辦法
var name = "this window";
var ding = {
  name = "this ding",
  getName = function () {
    var that = this; //1、將當(dāng)前對(duì)象存儲(chǔ)到一個(gè)變量
    return function () {
      return that.name; //2、引用存儲(chǔ)的這個(gè)變量即可
    }
  }
}
alert(ding .getName ()()); //this ding

2.3 內(nèi)存泄漏(IE9之前的版本,如果閉包作用域中保存著一個(gè)HTML元素,則該元素將無(wú)法銷(xiāo)毀釋放)

其實(shí)就是應(yīng)該被銷(xiāo)毀釋放內(nèi)存的對(duì)象沒(méi)有被銷(xiāo)毀釋放
函數(shù)執(zhí)行完成后,其內(nèi)部聲明的變量沒(méi)被銷(xiāo)毀釋放, 因?yàn)殚]包(匿名函數(shù))對(duì)這個(gè)變量存在引用。

function () {
  var element = document.getElementById("#demo");
  element.onclick = function () {
    alert(element.id);
  }
}
//解決辦法 將HTML元素存儲(chǔ)到另一個(gè)變量中
function () {
  var element = document.getElementById("#demo");、
  var id = element.id;
  element.onclick = function () { 
    alert(id);
  }
  element = null;
}

3、js模擬塊級(jí)作用域

目的就是為了減少向全局作用域添加變量與函數(shù)
一共兩種寫(xiě)法

//方法一
(function () {
  //這里就是塊級(jí)作用域了
})();//這對(duì)圓括號(hào)會(huì)立即調(diào)用這個(gè)匿名函數(shù)

//方法二
var getData = function () {
  //這里也是塊級(jí)作用域
}
getData();
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容