国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

【坑】JavaScript 對象方法執行的上下文

Lsnsh / 1322人閱讀

摘要:解決辦法知道了原因,很明顯解決辦法就是為要使用的方法綁定上下文。需要特別注意的是,只有在點操作之后馬上執行,才會有上下文,給人造成是調用了對象里面的方法的假象如果如上文描述那樣進行了賦值操作,則在執行的時候就不會有什么上下文了。

這是一個由于對 JavaScript 函數上下文理解不夠深入而遇到的坑。

背景

在表單驗證中,利用高階函數,抽象一個可以返回特定驗證邏輯的驗證函數:

// 正則匹配
const getParser = (type) => {
  switch (type) {
    case "chname":
      return /^([u4e00-u9fa5]+|([a-zA-Z]+s?)+)$/g;
    case "email":
      return /^[a-z0-9]+([._-]*[a-z0-9])*@([a-z0-9]+[-a-z0-9]*[a-z0-9]+.){1,63}[a-z0-9]+$/;
    case "phone":
      return /^(13[0-9]|14[5|7]|15[0|1|2|3|5|6|7|8|9]|18[0|1|2|3|5|6|7|8|9])d{8}$/;
    case "password":
      return /^(?=.*[A-Z])(?=.*[a-z])(?=.*[0-9])[a-zA-Z0-9!@#$%^&*()]{8,16}$/;
    default:
      return () => false;
  }
};
 
const getMatch = (value) => `${value}`.match;
const isValid = (value, type) => getMatch(value)(getParser(type));

isValid("12345678901", "phone");
問題

執行 getMatch(value)(getParser(type)) 的時候,無法完成驗證,程序陷入停止,無法往下執行。

原因

在執行形如 var a = obj.func 的代碼的時候,我們以為得到的變量 a 的上下文是 obj,然后執行 a() 的時候,就會跟執行 obj.func() 一樣;然而實際上,得到的 a 只是一個單純的函數,并不會自動綁定 obj 為上下文。

再來看上面的代碼的最后一句:

const isValid = (value, type) => getMatch(value)(getParser(type));

通過 getMatch(value) 得到一個 match 方法,但是與預期不同,此時得到的 match 方法的上下文并不是 value,因而會執行失敗。

解決辦法

知道了原因,很明顯解決辦法就是為要使用的 match 方法綁定上下文。在 Javascript 中,有很多種方法可以實現:

/// bind
const getMatch = (value) => `${value}`.match.bind(value);
const isValid = (value, type) => getMatch(value)(getParser(type));

/// call
const getMatch = (value) => `${value}`.match;
const isValid = (value, type) => getMatch(value).call(value, getParser(type));

/// apply
const getMatch = (value) => `${value}`.match;
const isValid = (value, type) => getMatch(value).apply(value, [getParser(type)]);
結論

JavaScript 的面向對象特性,比想象中還要弱一些。根本沒有什么 “類方法” ,所有形如 obj.func1() 的點操作方法執行,只不過是將 obj 作為上下文去執行 func1 函數罷了。需要特別注意的是,只有在點操作之后馬上執行,才會有上下文,給人造成是 “調用了對象 obj 里面的 func1 方法” 的假象;如果如上文描述那樣進行了賦值操作 func2 = obj.func1,則在執行 func2 的時候就不會有什么上下文了。

參考文章

Javascript 中的上下文,我的認識的三個階段
Javascript中的Bind,Call和Apply

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。

轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/86636.html

相關文章

  • JavaScript那些

    摘要:序列化為字符串之后它的各個屬性已經被解除了引用,重新相當于創建了一個新的對象。類似于的,的命令行終端。基本思路函數的使用以及協議。 多行注釋的陷阱 由于正則表達式字面量的存在,多行注釋可能會產生陷阱,例如以下程序將拋出錯誤: /* var a = /h*/.test(hello); */ 正則結束前的那個星號將被解析為注釋結束符,從而.被認為是不合法的.所以盡量避免使用多行注釋 整型 ...

    ivyzhang 評論0 收藏0
  • 透徹研究Javascript類型轉換

    摘要:注釋空數組空對象轉換為布爾型也是坑。系統會在自動類型轉換的時候調用他們,所以我們通常不需要手動調用他們。嚴格相等不存在類型轉換,對于類型不同的兩個值直接返回。 Javascript 中有5種基本類型(不包括 symbol),以及對象類型,他們在不同的運算中會被系統轉化為不同是類型,當然我們也可以手動轉化其類型。 Javascript 類型轉換中的坑極多,就連 Douglas Crock...

    dailybird 評論0 收藏0
  • javascript高級程序設計》函數調用模式 & this深度理解

    在上一篇文章(《javascript高級程序設計》筆記:Function類型)中稍微提及了一下函數對象的屬性—this,在這篇文章中有深入的說明: 函數的三種簡單調用模式 1 函數模式 定義的函數,如果單獨調用,不將其與任何對象關聯,那么就是函數調用模式 function fn(num1, num2) { console.log(this); } // 直接在全局調用 fn();// w...

    wyk1184 評論0 收藏0
  • JavaScript作用域學習筆記

    摘要:我們再來看一下第一段代碼小紅小黑腳本出錯腳本出錯在這段代碼中變量與函數,都擁有局部作用域。作用域鏈的最前端,始終都是當前執行代碼所在的作用域的變量對象。 個人博客原址 無論什么語言中,作用域都是一個十分重要的概念,在JavaScript中也不例外,作用域定義了變量或者函數有權訪問的范圍,決定了它們各自的行為。要理解JavaScript中的作用域首先就要知道:在let出現之前,JS中變...

    jerryloveemily 評論0 收藏0
  • JQuery,說說哪些大家都踩過

    摘要:回調在請求成功或失敗都會觸發。為避免多次執行,請先做事件解綁再重新綁定。避免響應多次執行錯誤使用指示符坑人指數指示符存在于一定的上下文中的,當上下文變化時指向不同的對象。 1 亂用選擇器 坑人指數:200 JQuery選擇器調用代價很大,反復調用效率更低。應采用緩存對象的方法或采用鏈式調用的方式。 //錯誤的寫法 $(#button).click(function(){ $(#...

    habren 評論0 收藏0

發表評論

0條評論

Lsnsh

|高級講師

TA的文章

閱讀更多
最新活動
閱讀需要支付1元查看
<