classnames解析class属性一览

224 阅读1分钟

本文参加了由公众号@若川视野 发起的每周源码共读活动,     点击了解详情一起参与。

【若川视野 x 源码共读】第26期 | # # classnames点击了解本期详情一起参与

1. 环境准备

去 github 的 classnames 仓库克隆项目。

2. 源码分析

从核心源码来看,解析分4种情况。

stateDiagram-v2
classNames --> 参数

参数 --> 1.如果是假值
参数 --> 2.如果是string或number
参数 --> 3.如果是数组
参数 --> 4.如果是object

1.如果是假值 --> 忽略
2.如果是string或number --> 直接添加
3.如果是数组 -->  递归
4.如果是object --> 判断toString

递归 -->  添加返回值

判断toString --> 如果没有重写 
判断toString --> 重写toString

如果没有重写 -->  迭代key属性,添加
重写toString -->  调用toString,添加

忽略 --> [*]
直接添加 --> [*]
添加返回值 --> [*]
迭代key属性,添加 --> [*]
调用toString,添加 --> [*]
var hasOwn = {}.hasOwnProperty;

function classNames() {
 var classes = [];

 for (var i = 0; i < arguments.length; i++) {
  var arg = arguments[i];
  if (!arg) continue;

  var argType = typeof arg;

  if (argType === 'string' || argType === 'number') {
   classes.push(arg);
  } else if (Array.isArray(arg)) {
   if (arg.length) {
    var inner = classNames.apply(null, arg);
    if (inner) {
     classes.push(inner);
    }
   }
  } else if (argType === 'object') {
   if (arg.toString === Object.prototype.toString) {
    for (var key in arg) {
     if (hasOwn.call(arg, key) && arg[key]) {
      classes.push(key);
     }
    }
   } else {
    classes.push(arg.toString());
   }
  }
 }

 return classes.join(' ');
}

3. 总结

项目中使用class属性时,有时会绑定变量,项目的开发人员有的习惯用对象绑定布尔值来控制,有的习惯用字符串,有的习惯用三元运算符,使用时会担心解析的结果会不会不一致,这次看了源码,知道解析的原理,觉得踏实了很多。