javascript防御性编程实践

本文将展示一些构造出自然混乱和难以理解的JavaScript代码的做法,这些做法都是反模式,严重违背了良好的编程原则,如何看待这些代码完全在于读者自己的需求。

基础版

示例 1:过度使用短路评估而不进行适当的参数校验

function calculateArea(width, height) {
  width = width || 50; // 应使用默认参数或者检查参数类型
  height = height || 100; // 这样可能导致逻辑错误,比如传入0时得到错误的默认值

  // 混淆意图的结构
  return (height, width, () => width * height)();
}

console.log(calculateArea(0, null)); // 期望得到0但却返回5000

示例 2:利用with语句混淆作用域

// 【不推荐】这样做会使得代码难以理解和维护
function updateObject(obj) {
  with(obj) {
    prop1 = prop1 || 'default value';
    prop2 = prop2 || 123;
    // 在这里,作用域链变得含糊不清
  }
}

const myObject = { prop1: undefined, prop2: null };
updateObject(myObject);
console.log(myObject.prop1); // 期望得到默认值,但实际上未定义

示例 3:制造多重嵌套和无意义的回调

// 【不推荐】无理由地创造回调地狱
function unnecessaryCallbacks() {
  setTimeout(() => {
    document.getElementById('someId').innerText = 'First Update';
    setTimeout(() => {
      document.getElementById('someId').innerText = 'Second Update';
      // 更多嵌套...
    }, 1000);
  }, 1000);
}

示例 4:使用eval进行执行动态代码

// 【不推荐】使用eval,这总是个坏主意
function unsafeEval(code) {
  eval(code); // eval可以执行任何代码,造成安全风险和调试困难
}

unsafeEval("console.log('This is unsafe');");

进阶版

示例 1:过度抽象和间接引用

过度使用层级和抽象可以让原本简单的操作变得难以理解。

const data = {
  value: 1,
  next: {
    value: 2,
    next: {
      value: 3,
      next: null
    }
  }
};

const getValue = field => obj => obj[field];
const nextField = getValue('next');
const valueField = getValue('value');

function getThirdValue(obj) {
  return nextField(nextField(nextField(obj)))(valueField(data));
}

console.log(getThirdValue(data)); // 输出: undefined

示例 2:晦涩难懂的函数复合

利用柯里化、高阶函数等技术编写过度复杂的代码。

function curry(fn, ...args1) {
  return (...args2) => args1.length + args2.length >= fn.length ?
    fn(...args1, ...args2) : curry(fn, ...args1, ...args2);
}

const sum = (a, b, c, d) => a + b + c + d;
const curriedSum = curry(sum);
const addFive = curriedSum(2)(3);
const total = addFive(5)(10);
console.log(total); // 输出: 20

示例 3:利用闭包和立即执行函数表达式来创建复杂作用域

这种做法会使得追踪变量的作用域和理解代码的逻辑变得非常困难。

let result = (function complexScope() {
  let hiddenValue = 1;
  return (function() {
    hiddenValue += 1;
    return (function() {
      hiddenValue += 1;
      return hiddenValue;
    })();
  })();
})();

console.log(result); // 输出: 3

示例 4:编写令人费解的递归函数

错误地使用递归或者故意使递归难以理解。

function obfuscateRecursion(start, end) {
  function innerFunction(x) {
    console.log(x);
    return x < end ? innerFunction.bind(null, x + 1) : null;
  }
  let fn = innerFunction(start);
  while(fn) fn = fn();
}

obfuscateRecursion(1, 5); // 依次打印1到5

示例 5:使用高度混淆的正则表达式

function validateEmail(email) {
  const regex = /(?:[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*|\"(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21\x23-\x5b\x5d-\x7f]|$\x01-\x09\x0b\x0c\x0e-\x7f])*\")@(?:(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:(?:[a-z0-9-]*[a-z0-9])?|$[\x01-\x09\x0b\x0c\x0e-\x7f]*$?))/
  return regex.test(email);
}

console.log(validateEmail('developer@example.com')); // 输出: true

原文链接:https://juejin.cn/post/7318083964107079707 作者:慕仲卿

(0)
上一篇 2023年12月30日 上午10:05
下一篇 2023年12月30日 上午10:15

相关推荐

发表回复

登录后才能评论