用JavaScript实现node.js中的path.join方法


发布者 ourjs  发布时间 1534004685034
关键字 JS学习  JavaScript 
Node.JS中的 path.join 非常方便,能直接按相对或绝对合并路径,使用: path.join([path1], [path2], [...]),有时侯前端也需要这种方法,如何实现呢?
其实直接从 node.js 的 path.js 拿到源码加工一下就可以了: 
1. 将 const 等 es6 属性改为 var,以便前端浏览器兼容
2. 添加一个判断路戏分隔符的变量 sep,即左斜杠还是右斜杠,以第一个路戏分隔符为准
3. 将引用的变量和函数放到一个文件里就可以了:

Path 的源码: https://github.com/nodejs/node/blob/master/lib/path.js


var CHAR_FORWARD_SLASH = 47
var CHAR_BACKWARD_SLASH = 92
var CHAR_DOT = 46
function isPathSeparator(code) {
  return code === CHAR_FORWARD_SLASH || code === CHAR_BACKWARD_SLASH;
}
function isPosixPathSeparator(code) {
  return code === CHAR_FORWARD_SLASH;
}
function normalize(path) {
  if (path.length === 0)
    return '.';
  var isAbsolute = path.charCodeAt(0) === CHAR_FORWARD_SLASH;
  var trailingSeparator =
    path.charCodeAt(path.length - 1) === CHAR_FORWARD_SLASH;
  // Normalize the path
  path = normalizeString(path, !isAbsolute, '/', isPosixPathSeparator);
  if (path.length === 0 && !isAbsolute)
    path = '.';
  if (path.length > 0 && trailingSeparator)
    path += '/';
  if (isAbsolute)
    return '/' + path;
  return path;
}
function normalizeString(path, allowAboveRoot, separator, isPathSeparator) {
  var res = '';
  var lastSegmentLength = 0;
  var lastSlash = -1;
  var dots = 0;
  var code;
  for (var i = 0; i <= path.length; ++i) {
    if (i < path.length)
      code = path.charCodeAt(i);
    else if (isPathSeparator(code))
      break;
    else
      code = CHAR_FORWARD_SLASH;
    if (isPathSeparator(code)) {
      if (lastSlash === i - 1 || dots === 1) {
        // NOOP
      } else if (lastSlash !== i - 1 && dots === 2) {
        if (res.length < 2 || lastSegmentLength !== 2 ||
            res.charCodeAt(res.length - 1) !== CHAR_DOT ||
            res.charCodeAt(res.length - 2) !== CHAR_DOT) {
          if (res.length > 2) {
            const lastSlashIndex = res.lastIndexOf(separator);
            if (lastSlashIndex !== res.length - 1) {
              if (lastSlashIndex === -1) {
                res = '';
                lastSegmentLength = 0;
              } else {
                res = res.slice(0, lastSlashIndex);
                lastSegmentLength = res.length - 1 - res.lastIndexOf(separator);
              }
              lastSlash = i;
              dots = 0;
              continue;
            }
          } else if (res.length === 2 || res.length === 1) {
            res = '';
            lastSegmentLength = 0;
            lastSlash = i;
            dots = 0;
            continue;
          }
        }
        if (allowAboveRoot) {
          if (res.length > 0)
            res += `${separator}..`;
          else
            res = '..';
          lastSegmentLength = 2;
        }
      } else {
        if (res.length > 0)
          res += separator + path.slice(lastSlash + 1, i);
        else
          res = path.slice(lastSlash + 1, i);
        lastSegmentLength = i - lastSlash - 1;
      }
      lastSlash = i;
      dots = 0;
    } else if (code === CHAR_DOT && dots !== -1) {
      ++dots;
    } else {
      dots = -1;
    }
  }
  return res;
}
function join() {
  if (arguments.length === 0)
    return '.';
  var sep = arguments[0].indexOf('/') > -1 ? '/' : '\\'
  var joined;
  var firstPart;
  for (var i = 0; i < arguments.length; ++i) {
    var arg = arguments[i];
    if (arg.length > 0) {
      if (joined === undefined)
        joined = firstPart = arg;
      else
        joined += sep + arg;
    }
  }
  if (joined === undefined)
    return '.';
  var needsReplace = true;
  var slashCount = 0;
  if (isPathSeparator(firstPart.charCodeAt(0))) {
    ++slashCount;
    var firstLen = firstPart.length;
    if (firstLen > 1) {
      if (isPathSeparator(firstPart.charCodeAt(1))) {
        ++slashCount;
        if (firstLen > 2) {
          if (isPathSeparator(firstPart.charCodeAt(2)))
            ++slashCount;
          else {
            // We matched a UNC path in the first part
            needsReplace = false;
          }
        }
      }
    }
  }
  if (needsReplace) {
    // Find any more consecutive slashes we need to replace
    for (; slashCount < joined.length; ++slashCount) {
      if (!isPathSeparator(joined.charCodeAt(slashCount)))
        break;
    }
    // Replace the slashes if needed
    if (slashCount >= 2)
      joined = sep + joined.slice(slashCount);
  }
  return normalize(joined);
}

使用:

join('../var/www', '../abc')
> "../var/abc"
join('../var/www', '\abc')
../var/www/abc






回复 (1)
  • #
  • #1 nen 1542022992020

微信扫码 立即评论




 热门文章 - 分享最多
  1. Git服务器搭建,多用户组权限控制配置,添加新用户密码登陆
  2. 设置select元素中option的默认值
  3. Node.JS用Path将相对路径转为绝对路径
  4. Office365并不是完全基于JavaScript重写的,只是用来构建UI界面
  5. 用JavaScript将input/textarea中的文本复制粘贴到剪切板
  6. Facebook 正在重构 React Native,将重写大量底层
  7. JavaScript用Number/parseInt/parseFloat判断字符串是否为数字
  8. Node.JS命令行或批处理中更改Linux用户密码
  9. 上海行业工资排名:产品经理一骑绝尘,前端排名第二?
  10. JavaScript中新建一个带全局变量参数的new Function动态函数

 相关阅读
  1. JavaScript中新建一个带全局变量参数的new Function动态函数
  2. 设置select元素中option的默认值
  3. JavaScript用Number/parseInt/parseFloat判断字符串是否为数字
  4. 用JavaScript将input/textarea中的文本复制粘贴到剪切板
  5. Node.JS用Path将相对路径转为绝对路径
  6. JS动态滑动切换到页面指定位置
  7. 如何通过网页、客户端、手机APP、路由器查找OnceAir NAS网盘的内网访问地址
  8. JavaScript用new Image实现内网服务器端口扫描
  9. 如何收集捕获Node中的未处理的错误异常信息?
  10. Node.JS循环删除非空文件夹及子目录下的所有文件

  开源的 OurJS
OurJS开源博客已经迁移到 OnceOA 平台。

  关注我们
扫一扫即可关注我们:
OnceJS

OnceOA