最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

javascript函數(shù)中的3個(gè)高級技巧

 更新時(shí)間:2016年09月22日 08:34:41   作者:小火柴的藍(lán)色理想  
這篇文章主要為大家詳細(xì)介紹了javascript函數(shù)中的3個(gè)高級技巧,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下

前面的話 

  函數(shù)對任何一門語言來說都是一個(gè)核心的概念,在javascript中更是如此。前面曾以深入理解函數(shù)系列的形式介紹了函數(shù)的相關(guān)內(nèi)容,本文將再深入一步,介紹函數(shù)的3個(gè)高級技巧  

技巧一:作用域安全的構(gòu)造函數(shù)

構(gòu)造函數(shù)其實(shí)就是一個(gè)使用new操作符調(diào)用的函數(shù) 

function Person(name,age,job){
  this.name=name;
  this.age=age;
  this.job=job;
}
var person=new Person('match',28,'Software Engineer');
console.log(person.name);//match

如果沒有使用new操作符,原本針對Person對象的三個(gè)屬性被添加到window對象 

function Person(name,age,job){
  this.name=name;
  this.age=age;
  this.job=job;
}     
var person=Person('match',28,'Software Engineer');
console.log(person);//undefined
console.log(window.name);//match

window的name屬性是用來標(biāo)識鏈接目標(biāo)和框架的,這里對該屬性的偶然覆蓋可能會導(dǎo)致頁面上的其它錯(cuò)誤,這個(gè)問題的解決方法就是創(chuàng)建一個(gè)作用域安全的構(gòu)造函數(shù) 

function Person(name,age,job){
  if(this instanceof Person){
    this.name=name;
    this.age=age;
    this.job=job;
  }else{
    return new Person(name,age,job);
  }
}
var person=Person('match',28,'Software Engineer');
console.log(window.name); // ""
console.log(person.name); //'match'
var person= new Person('match',28,'Software Engineer');
console.log(window.name); // ""
console.log(person.name); //'match'

但是,對構(gòu)造函數(shù)竊取模式的繼承,會帶來副作用。這是因?yàn)椋铝写a中,this對象并非Polygon對象實(shí)例,所以構(gòu)造函數(shù)Polygon()會創(chuàng)建并返回一個(gè)新的實(shí)例 

function Polygon(sides){
  if(this instanceof Polygon){
    this.sides=sides;
    this.getArea=function(){
      return 0;
    }
  }else{
    return new Polygon(sides);
  }
}
function Rectangle(wifth,height){
  Polygon.call(this,2);
  this.width=this.width;
  this.height=height;
  this.getArea=function(){
    return this.width * this.height;
  };
}
var rect= new Rectangle(5,10);
console.log(rect.sides); //undefined

如果要使用作用域安全的構(gòu)造函數(shù)竊取模式的話,需要結(jié)合原型鏈繼承,重寫Rectangle的prototype屬性,使它的實(shí)例也變成Polygon的實(shí)例 

function Polygon(sides){
  if(this instanceof Polygon){
    this.sides=sides;
    this.getArea=function(){
      return 0;
    }
  }else{
    return new Polygon(sides);
  }
}
function Rectangle(wifth,height){
  Polygon.call(this,2);
  this.width=this.width;
  this.height=height;
  this.getArea=function(){
    return this.width * this.height;
  };
}
Rectangle.prototype= new Polygon();
var rect= new Rectangle(5,10);
console.log(rect.sides); //2

技巧二:惰性載入函數(shù)

因?yàn)楦鳛g覽器之間的行為的差異,我們經(jīng)常會在函數(shù)中包含了大量的if語句,以檢查瀏覽器特性,解決不同瀏覽器的兼容問題。比如,我們最常見的為dom節(jié)點(diǎn)添加事件的函數(shù) 

function addEvent(type, element, fun) {
  if (element.addEventListener) {
    element.addEventListener(type, fun, false);
  }
  else if(element.attachEvent){
    element.attachEvent('on' + type, fun);
  }
  else{
    element['on' + type] = fun;
  }
}

每次調(diào)用addEvent函數(shù)的時(shí)候,它都要對瀏覽器所支持的能力進(jìn)行檢查,首先檢查是否支持addEventListener方法,如果不支持,再檢查是否支持attachEvent方法,如果還不支持,就用dom0級的方法添加事件。這個(gè)過程,在addEvent函數(shù)每次調(diào)用的時(shí)候都要走一遍,其實(shí),如果瀏覽器支持其中的一種方法,那么他就會一直支持了,就沒有必要再進(jìn)行其他分支的檢測了。也就是說,if語句不必每次都執(zhí)行,代碼可以運(yùn)行的更快一些。

解決方案就是惰性載入。所謂惰性載入,指函數(shù)執(zhí)行的分支只會發(fā)生一次

有兩種實(shí)現(xiàn)惰性載入的方式 

【1】第一種是在函數(shù)被調(diào)用時(shí),再處理函數(shù)。函數(shù)在第一次調(diào)用時(shí),該函數(shù)會被覆蓋為另外一個(gè)按合適方式執(zhí)行的函數(shù),這樣任何對原函數(shù)的調(diào)用都不用再經(jīng)過執(zhí)行的分支了

我們可以用下面的方式使用惰性載入重寫addEvent() 

function addEvent(type, element, fun) {
  if (element.addEventListener) {
    addEvent = function (type, element, fun) {
      element.addEventListener(type, fun, false);
    }
  }
  else if(element.attachEvent){
    addEvent = function (type, element, fun) {
      element.attachEvent('on' + type, fun);
    }
  }
  else{
    addEvent = function (type, element, fun) {
      element['on' + type] = fun;
    }
  }
  return addEvent(type, element, fun);
}

在這個(gè)惰性載入的addEvent()中,if語句的每個(gè)分支都會為addEvent變量賦值,有效覆蓋了原函數(shù)。最后一步便是調(diào)用了新賦函數(shù)。下一次調(diào)用addEvent()時(shí),便會直接調(diào)用新賦值的函數(shù),這樣就不用再執(zhí)行if語句了

但是,這種方法有個(gè)缺點(diǎn),如果函數(shù)名稱有所改變,修改起來比較麻煩 

【2】第二種是聲明函數(shù)時(shí)就指定適當(dāng)?shù)暮瘮?shù)。 這樣在第一次調(diào)用函數(shù)時(shí)就不會損失性能了,只在代碼加載時(shí)會損失一點(diǎn)性能

以下就是按照這一思路重寫的addEvent()。以下代碼創(chuàng)建了一個(gè)匿名的自執(zhí)行函數(shù),通過不同的分支以確定應(yīng)該使用哪個(gè)函數(shù)實(shí)現(xiàn) 

var addEvent = (function () {
  if (document.addEventListener) {
    return function (type, element, fun) {
      element.addEventListener(type, fun, false);
    }
  }
  else if (document.attachEvent) {
    return function (type, element, fun) {
      element.attachEvent('on' + type, fun);
    }
  }
  else {
    return function (type, element, fun) {
      element['on' + type] = fun;
    }
  }
})();

技巧三:函數(shù)綁定

在javascript與DOM交互中經(jīng)常需要使用函數(shù)綁定,定義一個(gè)函數(shù)然后將其綁定到特定DOM元素或集合的某個(gè)事件觸發(fā)程序上,綁定函數(shù)經(jīng)常和回調(diào)函數(shù)及事件處理程序一起使用,以便把函數(shù)作為變量傳遞的同時(shí)保留代碼執(zhí)行環(huán)境 

<button id="btn">按鈕</button>
<script>      
  var handler={
    message:"Event handled.",
    handlerFun:function(){
      alert(this.message);
    }
  };
btn.onclick = handler.handlerFun;
</script>

上面的代碼創(chuàng)建了一個(gè)叫做handler的對象。handler.handlerFun()方法被分配為一個(gè)DOM按鈕的事件處理程序。當(dāng)按下該按鈕時(shí),就調(diào)用該函數(shù),顯示一個(gè)警告框。雖然貌似警告框應(yīng)該顯示Event handled,然而實(shí)際上顯示的是undefiend。這個(gè)問題在于沒有保存handler.handleClick()的環(huán)境,所以this對象最后是指向了DOM按鈕而非handler

可以使用閉包來修正這個(gè)問題 

<button id="btn">按鈕</button>
<script>      
var handler={
  message:"Event handled.",
  handlerFun:function(){
    alert(this.message);
  }
};
btn.onclick = function(){
  handler.handlerFun();  
}
</script>

當(dāng)然這是特定于此場景的解決方案,創(chuàng)建多個(gè)閉包可能會令代碼難以理解和調(diào)試。更好的辦法是使用函數(shù)綁定
一個(gè)簡單的綁定函數(shù)bind()接受一個(gè)函數(shù)和一個(gè)環(huán)境,并返回一個(gè)在給定環(huán)境中調(diào)用給定函數(shù)的函數(shù),并且將所有參數(shù)原封不動傳遞過去 

function bind(fn,context){
  return function(){
    return fn.apply(context,arguments);
  }
} 

這個(gè)函數(shù)似乎簡單,但其功能是非常強(qiáng)大的。在bind()中創(chuàng)建了一個(gè)閉包,閉包使用apply()調(diào)用傳入的函數(shù),并給apply()傳遞context對象和參數(shù)。當(dāng)調(diào)用返回的函數(shù)時(shí),它會在給定環(huán)境中執(zhí)行被傳入的函數(shù)并給出所有參數(shù) 

<button id="btn">按鈕</button>
<script> 
function bind(fn,context){
  return function(){
    return fn.apply(context,arguments);
  }
}     
var handler={
  message:"Event handled.",
  handlerFun:function(){
    alert(this.message);
  }
};
btn.onclick = bind(handler.handlerFun,handler);
</script>

ECMAScript5為所有函數(shù)定義了一個(gè)原生的bind()方法,進(jìn)一步簡化了操作。

只要是將某個(gè)函數(shù)指針以值的形式進(jìn)行傳遞,同時(shí)該函數(shù)必須在特定環(huán)境中執(zhí)行,被綁定函數(shù)的效用就突顯出來了。它們主要用于事件處理程序以及setTimeout()和setInterval()。然而,被綁定函數(shù)與普通函數(shù)相比有更多的開銷,它們需要更多內(nèi)存,同時(shí)也因?yàn)槎嘀睾瘮?shù)調(diào)用稍微慢一點(diǎn),所以最好只在必要時(shí)使用。

以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • JavaScript 中.call()的使用小結(jié)

    JavaScript 中.call()的使用小結(jié)

    .call()是JavaScript中用于顯式設(shè)置函數(shù)執(zhí)行上下文并立即調(diào)用該函數(shù)的方法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2024-11-11
  • js實(shí)現(xiàn)圖片緩慢放大縮小效果

    js實(shí)現(xiàn)圖片緩慢放大縮小效果

    這篇文章主要為大家詳細(xì)介紹了js實(shí)現(xiàn)圖片緩慢放大縮小效果的相關(guān)資料,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2016-08-08
  • js使用DOM設(shè)置單選按鈕、復(fù)選框及下拉菜單的方法

    js使用DOM設(shè)置單選按鈕、復(fù)選框及下拉菜單的方法

    這篇文章主要介紹了js使用DOM設(shè)置單選按鈕、復(fù)選框及下拉菜單的方法,較為詳細(xì)的分析了單選按鈕、復(fù)選框及下拉菜單的具體用法及實(shí)現(xiàn)技巧,非常具有實(shí)用價(jià)值,需要的朋友可以參考下
    2015-01-01
  • JS實(shí)現(xiàn)快遞單打印功能【推薦】

    JS實(shí)現(xiàn)快遞單打印功能【推薦】

    這篇文章主要介紹了JS實(shí)現(xiàn)快遞單打印功能,給大家介紹了js網(wǎng)頁打印的幾種方法,非常不錯(cuò),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2018-06-06
  • 有趣的思路~~JS仿 WINXP 注銷桌面漸隱效果

    有趣的思路~~JS仿 WINXP 注銷桌面漸隱效果

    有趣的思路~~JS仿 WINXP 注銷桌面漸隱效果...
    2006-10-10
  • Javascript圖片上傳前的本地預(yù)覽實(shí)例

    Javascript圖片上傳前的本地預(yù)覽實(shí)例

    圖片的上傳預(yù)覽功能主要用于圖片上傳前的一個(gè)效果的預(yù)覽,這篇文章主要介紹了Javascript圖片上傳前的本地預(yù)覽實(shí)例,需要的朋友可以參考下
    2014-06-06
  • 一文快速弄懂webpack動態(tài)import原理

    一文快速弄懂webpack動態(tài)import原理

    無論你開發(fā)使用的是CommonJS規(guī)范還是ES6模塊規(guī)范,打包后的文件都統(tǒng)一使用webpack自定義的模塊規(guī)范來管理、加載模塊,下面這篇文章主要給大家介紹了關(guān)于webpack動態(tài)import原理的相關(guān)資料,需要的朋友可以參考下
    2022-04-04
  • JavaScript Tips 使用DocumentFragment加快DOM渲染速度

    JavaScript Tips 使用DocumentFragment加快DOM渲染速度

    大家在開發(fā)JavaScript應(yīng)用的時(shí)候,如果遇到這種大量節(jié)點(diǎn)的情況,不妨將DocumentFragment作為一個(gè)備選的方案。
    2010-06-06
  • JavaScript引用類型Function實(shí)例詳解

    JavaScript引用類型Function實(shí)例詳解

    這篇文章主要介紹了JavaScript引用類型Function,結(jié)合實(shí)例形式詳細(xì)分析了javascript引用類型Function概念、定義、原理、相關(guān)使用技巧與操作注意事項(xiàng),需要的朋友可以參考下
    2018-08-08
  • Javascript 引擎工作機(jī)制詳解

    Javascript 引擎工作機(jī)制詳解

    我們需要引入幾個(gè)相關(guān)的概念:執(zhí)行環(huán)境棧、全局對象、執(zhí)行環(huán)境、變量對象、活動對象、作用域和作用域鏈等,這些概念正是JS引擎工作的核心組件。這篇文章的目的不是孤立的為你講解每一個(gè)概念需要的朋友可以參考下
    2016-11-11

最新評論

黄龙县| 沙湾县| 共和县| 锦屏县| 萨嘎县| 昌宁县| 昆山市| SHOW| 正镶白旗| 班玛县| 大邑县| 莒南县| 合山市| 唐山市| 阳曲县| 乐山市| 托克逊县| 浮山县| 陈巴尔虎旗| 阜阳市| 兴宁市| 临江市| 孙吴县| 新丰县| 新野县| 扎兰屯市| 佛教| 惠州市| 榆林市| 三河市| 礼泉县| 正定县| 吴旗县| 乌海市| 仙游县| 南乐县| 溆浦县| 木兰县| 庆安县| 多伦县| 龙海市|