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


Posted in Javascript onAugust 12, 2018

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

总结

以上所述是小编给大家介绍的使用JavaScript实现node.js中的path.join方法,希望对大家有所帮助,如果对大家有所帮助,如果大家有任何疑问欢迎给我留言,小编会及时回复大家的!

Javascript 相关文章推荐
JS 判断undefined的实现代码
Nov 26 Javascript
Javascript 设计模式(二) 闭包
May 26 Javascript
html+javascript实现可拖动可提交的弹出层对话框效果
Aug 05 Javascript
你所不了解的javascript操作DOM的细节知识点(一)
Jun 17 Javascript
jQuery Validate插件实现表单验证
Aug 19 Javascript
微信小程序 实现拖拽事件监听实例详解
Nov 16 Javascript
ionic2 tabs 图标自定义实例
Mar 08 Javascript
jQuery is not defined 错误原因与解决方法小结
Mar 19 Javascript
JavaScript中正则表达式使数字、中文或指定字符高亮显示
Oct 31 Javascript
vue cli 3.0 使用全过程解析
Jun 14 Javascript
mapboxgl区划标签避让不遮盖实现的代码详解
Jul 01 Javascript
解决vue 给window添加和移除resize事件遇到的坑
Jul 21 Javascript
在小程序中集成redux/immutable/thunk第三方库的方法
Aug 12 #Javascript
Vue实现左右菜单联动实现代码
Aug 12 #Javascript
Vue中的v-for循环key属性注意事项小结
Aug 12 #Javascript
vue实现商品加减计算总价的实例代码
Aug 12 #Javascript
Vue.js中使用iView日期选择器并设置开始时间结束时间校验功能
Aug 12 #Javascript
深入理解Vue父子组件生命周期执行顺序及钩子函数
Aug 12 #Javascript
VUE在for循环里面根据内容值动态的加入class值的方法
Aug 12 #Javascript
You might like
PHILIPS D1835/D1875的电路分析与打理
2021/03/02 无线电
以文本方式上传二进制文件的PHP程序
2006/10/09 PHP
PHP随机生成信用卡卡号的方法
2015/03/23 PHP
php超快高效率统计大文件行数
2015/07/05 PHP
PHP 数组基本操作小结(推荐)
2016/06/13 PHP
注意!PHP 7中不要做的10件事
2016/09/18 PHP
PHP删除二维数组中相同元素及数组重复值的方法示例
2017/05/05 PHP
PHP PDOStatement::bindParam讲解
2019/01/30 PHP
php-fpm超时时间设置request_terminate_timeout资源问题分析
2019/09/27 PHP
基于JQuery的一句话搞定手风琴菜单
2012/09/14 Javascript
使用jQuery同时控制四张图片的伸缩实现代码
2013/04/19 Javascript
利用window.name实现windowStorage代码分享
2014/01/02 Javascript
JavaScript修改浏览器tab标题小技巧
2015/01/06 Javascript
jQuery实现网页抖动的菜单抖动效果
2015/08/07 Javascript
javascript 数组的正态分布排序的问题
2016/07/31 Javascript
Angularjs的ng-repeat中去除重复数据的方法
2016/08/05 Javascript
bootstrap精简教程_动力节点Java学院整理
2017/07/14 Javascript
js 概率计算(简单版)
2017/09/12 Javascript
JS使用正则表达式提交页面验证的代码
2019/10/16 Javascript
JS实现字体背景跑马灯
2020/01/06 Javascript
vue Element左侧无限级菜单实现
2020/06/10 Javascript
对Python中的@classmethod用法详解
2018/04/21 Python
对numpy中的transpose和swapaxes函数详解
2018/08/02 Python
python 实现交换两个列表元素的位置示例
2019/06/26 Python
django admin组件使用方法详解
2019/07/19 Python
Python搭建代理IP池实现存储IP的方法
2019/10/27 Python
python中的TCP(传输控制协议)用法实例分析
2019/11/15 Python
Python如何安装第三方模块
2020/05/28 Python
python3爬虫GIL修改多线程实例讲解
2020/11/24 Python
Python操作Excel的学习笔记
2021/02/18 Python
纽约通行卡:The New York Pass(免费游览纽约90多个景点)
2017/07/29 全球购物
屈臣氏乌克兰:Watsons UA
2019/10/29 全球购物
C#如何进行LDAP用户校验
2012/11/21 面试题
党的群众路线教育实践活动总结报告
2014/04/28 职场文书
幼儿园安全责任书范本
2014/07/24 职场文书
护理培训心得体会
2016/01/22 职场文书