【坑】JavaScript 对象要领实行的上下文

这是一个因为对 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

    原文作者:陈某
    原文地址: https://segmentfault.com/a/1190000007907028
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞