摘要:解決辦法知道了原因,很明顯解決辦法就是為要使用的方法綁定上下文。需要特別注意的是,只有在點操作之后馬上執(zhí)行,才會有上下文,給人造成是調(diào)用了對象里面的方法的假象如果如上文描述那樣進行了賦值操作,則在執(zhí)行的時候就不會有什么上下文了。
這是一個由于對 JavaScript 函數(shù)上下文理解不夠深入而遇到的坑。
背景在表單驗證中,利用高階函數(shù),抽象一個可以返回特定驗證邏輯的驗證函數(shù):
// 正則匹配 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");問題
執(zhí)行 getMatch(value)(getParser(type)) 的時候,無法完成驗證,程序陷入停止,無法往下執(zhí)行。
原因在執(zhí)行形如 var a = obj.func 的代碼的時候,我們以為得到的變量 a 的上下文是 obj,然后執(zhí)行 a() 的時候,就會跟執(zhí)行 obj.func() 一樣;然而實際上,得到的 a 只是一個單純的函數(shù),并不會自動綁定 obj 為上下文。
再來看上面的代碼的最后一句:
const isValid = (value, type) => getMatch(value)(getParser(type));
通過 getMatch(value) 得到一個 match 方法,但是與預期不同,此時得到的 match 方法的上下文并不是 value,因而會執(zhí)行失敗。
解決辦法知道了原因,很明顯解決辦法就是為要使用的 match 方法綁定上下文。在 Javascript 中,有很多種方法可以實現(xiàn):
/// 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 的面向?qū)ο筇匦裕认胂笾羞€要弱一些。根本沒有什么 “類方法” ,所有形如 obj.func1() 的點操作方法執(zhí)行,只不過是將 obj 作為上下文去執(zhí)行 func1 函數(shù)罷了。需要特別注意的是,只有在點操作之后馬上執(zhí)行,才會有上下文,給人造成是 “調(diào)用了對象 obj 里面的 func1 方法” 的假象;如果如上文描述那樣進行了賦值操作 func2 = obj.func1,則在執(zhí)行 func2 的時候就不會有什么上下文了。
參考文章Javascript 中的上下文,我的認識的三個階段
Javascript中的Bind,Call和Apply
文章版權歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/86636.html
摘要:序列化為字符串之后它的各個屬性已經(jīng)被解除了引用,重新相當于創(chuàng)建了一個新的對象。類似于的,的命令行終端。基本思路函數(shù)的使用以及協(xié)議。 多行注釋的陷阱 由于正則表達式字面量的存在,多行注釋可能會產(chǎn)生陷阱,例如以下程序?qū)伋鲥e誤: /* var a = /h*/.test(hello); */ 正則結束前的那個星號將被解析為注釋結束符,從而.被認為是不合法的.所以盡量避免使用多行注釋 整型 ...
摘要:注釋空數(shù)組空對象轉(zhuǎn)換為布爾型也是坑。系統(tǒng)會在自動類型轉(zhuǎn)換的時候調(diào)用他們,所以我們通常不需要手動調(diào)用他們。嚴格相等不存在類型轉(zhuǎn)換,對于類型不同的兩個值直接返回。 Javascript 中有5種基本類型(不包括 symbol),以及對象類型,他們在不同的運算中會被系統(tǒng)轉(zhuǎn)化為不同是類型,當然我們也可以手動轉(zhuǎn)化其類型。 Javascript 類型轉(zhuǎn)換中的坑極多,就連 Douglas Crock...
在上一篇文章(《javascript高級程序設計》筆記:Function類型)中稍微提及了一下函數(shù)對象的屬性—this,在這篇文章中有深入的說明: 函數(shù)的三種簡單調(diào)用模式 1 函數(shù)模式 定義的函數(shù),如果單獨調(diào)用,不將其與任何對象關聯(lián),那么就是函數(shù)調(diào)用模式 function fn(num1, num2) { console.log(this); } // 直接在全局調(diào)用 fn();// w...
摘要:我們再來看一下第一段代碼小紅小黑腳本出錯腳本出錯在這段代碼中變量與函數(shù),都擁有局部作用域。作用域鏈的最前端,始終都是當前執(zhí)行代碼所在的作用域的變量對象。 個人博客原址 無論什么語言中,作用域都是一個十分重要的概念,在JavaScript中也不例外,作用域定義了變量或者函數(shù)有權訪問的范圍,決定了它們各自的行為。要理解JavaScript中的作用域首先就要知道:在let出現(xiàn)之前,JS中變...
摘要:回調(diào)在請求成功或失敗都會觸發(fā)。為避免多次執(zhí)行,請先做事件解綁再重新綁定。避免響應多次執(zhí)行錯誤使用指示符坑人指數(shù)指示符存在于一定的上下文中的,當上下文變化時指向不同的對象。 1 亂用選擇器 坑人指數(shù):200 JQuery選擇器調(diào)用代價很大,反復調(diào)用效率更低。應采用緩存對象的方法或采用鏈式調(diào)用的方式。 //錯誤的寫法 $(#button).click(function(){ $(#...
閱讀 1659·2019-08-30 13:04
閱讀 2208·2019-08-30 12:59
閱讀 1773·2019-08-29 18:34
閱讀 1865·2019-08-29 17:31
閱讀 1260·2019-08-29 15:42
閱讀 3540·2019-08-29 15:37
閱讀 2862·2019-08-29 13:45
閱讀 2775·2019-08-26 13:57