JavaScript 设计模式与安全实践指南

一、设计模式:提升代码可维护性

1. 工厂模式:灵活的对象创建

工厂模式通过将对象创建逻辑封装在单独的函数中,避免直接使用 new 操作符。

class Car {
  constructor(model, year) {
    this.model = model;
    this.year = year;
  }
}

function createCar(model, year) {
  return new Car(model, year);
}

const myCar = createCar('Tesla', 2023);

实践建议

  • 适用于需要创建多个相似对象的场景
  • 当对象创建过程复杂时,工厂模式能简化调用方代码

2. 单例模式:确保唯一实例

单例模式确保一个类只有一个实例,并提供全局访问点。

class Database {
  constructor() {
    if (Database.instance) {
      return Database.instance;
    }
    this.connection = "established";
    Database.instance = this;
  }
}

const db1 = new Database();
const db2 = new Database();
console.log(db1 === db2); // true

实践建议

  • 适用于全局状态管理(如Redux store)
  • 可用于数据库连接池等资源密集型对象

3. 观察者模式:实现松耦合通信

观察者模式定义对象间的一对多依赖关系,当一个对象状态改变时,所有依赖它的对象都会得到通知。

图1

class NewsPublisher {
  constructor() {
    this.subscribers = [];
  }

  subscribe(subscriber) {
    this.subscribers.push(subscriber);
  }

  publish(news) {
    this.subscribers.forEach(sub => sub.update(news));
  }
}

class Subscriber {
  update(news) {
    console.log(`Received news: ${news}`);
  }
}

const publisher = new NewsPublisher();
const sub1 = new Subscriber();
publisher.subscribe(sub1);
publisher.publish("JavaScript 2023新特性发布!");

实践建议

  • 适用于事件驱动架构
  • Vue的响应式系统和React的Hooks都借鉴了观察者模式思想

二、前端安全防护

1. XSS防御:三种类型与防护措施

XSS(跨站脚本攻击)主要分为三类:

  1. 存储型XSS:恶意脚本存储在服务器
  2. 反射型XSS:恶意脚本作为请求的一部分
  3. DOM型XSS:客户端直接操作DOM导致

防御方案

// 转义HTML
function escapeHtml(unsafe) {
  return unsafe
    .replace(/&/g, "&")
    .replace(/</g, "&lt;")
    .replace(/>/g, "&gt;")
    .replace(/"/g, "&quot;")
    .replace(/'/g, "&#039;");
}

// 现代框架已内置XSS防护
// React: 自动转义JSX中的变量
// Vue: v-text指令自动转义

2. CSRF防护:多重防御策略

CSRF(跨站请求伪造)防御组合拳:

  1. SameSite Cookie

    // 服务器设置Cookie时
    Set-Cookie: sessionid=xxxx; SameSite=Strict; Secure
  2. CSRF Token

    <form action="/transfer" method="POST">
      <input type="hidden" name="_csrf" value="随机token">
      <!-- 其他表单字段 -->
    </form>
  3. 双重Cookie验证

    // 前端从Cookie中读取token并添加到请求头
    fetch('/api/data', {
      headers: {
     'X-CSRF-TOKEN': getCookie('csrfToken')
      }
    });

3. Content Security Policy (CSP)

CSP通过HTTP头定义可信任的内容来源:

Content-Security-Policy: 
  default-src 'self';
  script-src 'self' https://trusted.cdn.com;
  img-src *;
  style-src 'self' 'unsafe-inline';
  connect-src https://api.example.com;

策略说明

  • default-src: 默认回退规则
  • script-src: 控制JavaScript加载源
  • 'unsafe-inline': 允许内联脚本(慎用)
  • report-uri: 违规报告地址

三、现代工具链深度集成

1. Webpack优化配置

// webpack.config.js
module.exports = {
  entry: './src/index.js',
  output: {
    filename: '[name].[contenthash:8].js',
    path: path.resolve(__dirname, 'dist'),
  },
  module: {
    rules: [
      {
        test: /\.js$/,
        exclude: /node_modules/,
        use: {
          loader: 'babel-loader',
          options: {
            presets: ['@babel/preset-env']
          }
        }
      }
    ]
  },
  plugins: [
    new HtmlWebpackPlugin(),
    new MiniCssExtractPlugin()
  ],
  optimization: {
    splitChunks: {
      chunks: 'all'
    }
  }
};

关键优化点

  • 代码分割(Code Splitting)
  • 持久化缓存(contenthash)
  • Tree Shaking(需配合ES模块)

2. Babel转译策略

.babelrc 配置示例:

{
  "presets": [
    ["@babel/preset-env", {
      "targets": "> 0.25%, not dead",
      "useBuiltIns": "usage",
      "corejs": 3
    }]
  ],
  "plugins": [
    "@babel/plugin-proposal-class-properties"
  ]
}

实践建议

  • 按需引入polyfill(useBuiltIns: 'usage')
  • 区分开发和生产环境配置
  • 配合browserslist定义目标环境

3. ESLint规范配置

// .eslintrc.js
module.exports = {
  env: {
    browser: true,
    es2021: true
  },
  extends: [
    'eslint:recommended',
    'plugin:react/recommended'
  ],
  parserOptions: {
    ecmaVersion: 12,
    sourceType: 'module'
  },
  rules: {
    'no-console': 'warn',
    'react/prop-types': 'off',
    'semi': ['error', 'always']
  }
};

集成建议

  • 结合Prettier统一代码风格
  • 添加Husky实现提交前检查
  • 重要项目开启CI/CD流水线检查

四、框架特性解析

1. React Hooks原理

import { useState, useEffect } from 'react';

function Counter() {
  const [count, setCount] = useState(0);
  
  useEffect(() => {
    document.title = `Count: ${count}`;
    return () => console.log('cleanup');
  }, [count]);

  return (
    <button onClick={() => setCount(c => c + 1)}>
      Clicked {count} times
    </button>
  );
}

Hooks规则

  1. 只在顶层调用Hooks
  2. 只在React函数中调用
  3. 依赖数组需完整声明

2. Vue响应式原理

Vue3使用Proxy实现响应式:

const reactive = (target) => {
  return new Proxy(target, {
    get(obj, key) {
      track(obj, key); // 依赖收集
      return Reflect.get(obj, key);
    },
    set(obj, key, value) {
      Reflect.set(obj, key, value);
      trigger(obj, key); // 触发更新
      return true;
    }
  });
};

function ref(value) {
  const refObj = {
    get value() {
      track(refObj, 'value');
      return value;
    },
    set value(newVal) {
      value = newVal;
      trigger(refObj, 'value');
    }
  };
  return refObj;
}

优化技巧

  • 合理使用shallowRef/shallowReactive减少响应式开销
  • 复杂计算使用computed缓存
  • 批量更新使用nextTick

总结与最佳实践

  1. 设计模式选择

    • UI组件使用工厂模式
    • 全局状态使用单例模式
    • 跨组件通信使用观察者模式
  2. 安全防护

    • 所有动态内容必须转义
    • 关键操作必须CSRF防护
    • 生产环境必须配置CSP
  3. 工具链优化

    • 开发环境启用sourcemap
    • 生产环境开启代码压缩
    • 使用ESLint+Prettier统一风格
  4. 框架使用

    • React避免滥用useEffect
    • Vue合理使用v-once优化
    • 大型项目考虑状态管理方案

通过合理应用这些模式和技术,可以构建出更安全、更易维护的高质量JavaScript应用。

评论已关闭