啸佳葛革 發表於 2019-5-31 14:45:00

JavaScript 系列--JavaScript一些奇淫技巧的实现方法(二)数字格式化 1234567890转1,234,567,890;argruments 对象(类数组)转换成数组

<p><strong><span style="font-size: large">一、前言</span></strong></p>
<p>之前写了一篇文章:<span style="font-size: small">JavaScript 系列--JavaScript一些奇淫技巧的实现方法(一)简短的sleep函数,获取时间戳</span></p>
<p>https://www.mwcxs.top/page/746.html</p>
<p>介绍了sleep函数和获取时间戳的方法。接下来我们来介绍数字格式化1234567890&nbsp;--&gt;&nbsp;1,234,567,890</p>
<p>&nbsp;</p>
<p><strong><span style="font-size: large">二、数字格式化&nbsp;1234567890&nbsp;--&gt;&nbsp;1,234,567,890</span></strong></p>
<p><strong>1、普通版</strong></p>
<pre><code class="javascript hljs"><span class="hljs-comment">// 数字格式化 1234567890 --&gt; 1,234,567,890
<span class="hljs-function"><span class="hljs-keyword">function <span class="hljs-title">formatNumber(<span class="hljs-params">str){
    <span class="hljs-keyword">var arr = [];
    <span class="hljs-keyword">var count = str.length;
    <span class="hljs-keyword">while(count&gt;=<span class="hljs-number">3){
      arr.unshift(str.slice(count - <span class="hljs-number">3, count));
      count -= <span class="hljs-number">3;
    }
    // 如果是不是3的倍数就另外追加到上去<br>    str.length % <span class="hljs-number">3 &amp;&amp; arr.unshift(str.slice(<span class="hljs-number">0, str.length % <span class="hljs-number">3));
    <span class="hljs-keyword">return arr.toString();
}
formatNumber(<span class="hljs-string">'1234567890')</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></code></pre>
<p>优点:自我感觉比网上写的一堆 for循环 还有 if-else 判断的逻辑更加清晰直白。<br>缺点:太普通</p>
<p>&nbsp;</p>
<p><strong>2、进阶版</strong></p>
<pre><code class="javascript hljs"><span class="hljs-comment">// 2、进阶版
<span class="hljs-function"><span class="hljs-keyword">function <span class="hljs-title">formatNumber(<span class="hljs-params">str){
    <span class="hljs-keyword">return str.split(<span class="hljs-string">"").reverse().reduce((prev,next,index) =&gt; {
      <span class="hljs-keyword">return ((index%<span class="hljs-number">3)? next: (next+<span class="hljs-string">',')) + prev;
    })
}
formatNumber(<span class="hljs-string">"1234567890");</span></span></span></span></span></span></span></span></span></span></span></code></pre>
<p>优点:把 JS 的 API 玩的了如指掌<br>缺点:不好理解</p>
<p>&nbsp;</p>
<p><strong>3、正则版</strong></p>
<pre><code class="javascript hljs"><span class="hljs-function"><span class="hljs-keyword">function <span class="hljs-title">formatNumber(<span class="hljs-params">str){
    <span class="hljs-keyword">return str.replace(/(?!^)(?=(\d{3})+$)/g,<span class="hljs-string">',')
}
formatNumber(<span class="hljs-string">"1234567890");</span></span></span></span></span></span></span></code></pre>
<p>我们来看看正则的分析:</p>
<p>(1)/(?!^)(?=(\d{3})+\b)/g:匹配的这个位置不能是开头(?!^)</p>
<p>(2)(\d{3})+:必须是1个或者多个的3个连续数字</p>
<p>优点:代码少,简洁。</p>
<p>缺点:正则表达式的位置匹配很重要,可以参考这个:https://www.mwcxs.top/page/587.html</p>
<p>&nbsp;</p>
<p><strong>4、API版本</strong></p>
<pre><code class="javascript hljs">(<span class="hljs-number">1234567890).toLocaleString(<span class="hljs-string">'en-us');
(1234567890).toLocaleString();
1234567890..toLocaleString();</span></span></code></pre>
<p>你可能还不知道&nbsp;<code>JavaScript</code>&nbsp;的&nbsp;<code>toLocaleString</code>&nbsp;还可以这么玩。</p>
<pre><code class="javascript hljs"><span class="hljs-number">123456789..toLocaleString(<span class="hljs-string">'zh-hans-cn-u-nu-hanidec',{useGrouping: <span class="hljs-literal">false}); <span class="hljs-comment">//"一二三四五六七八九"
<span class="hljs-number">123456789..toLocaleString(<span class="hljs-string">'zh-hans-cn-u-nu-hanidec',{useGrouping: <span class="hljs-literal">false}); <span class="hljs-comment">//"一二三,四五六,七八九"
<span class="hljs-keyword">new <span class="hljs-built_in">Date().toLocaleString(<span class="hljs-string">'zh-hans-cn-u-nu-hanidec'); <span class="hljs-comment">//"二〇一九/五/二九 下午三:一五:四〇"</span></span></span></span></span></span></span></span></span></span></span></span></code></pre>
<p>还可以使用Intl对象,</p>
<blockquote>
<p>Intl 对象是 ECMAScript 国际化 API 的一个命名空间,它提供了精确的字符串对比,数字格式化,日期和时间格式化。Collator,NumberFormat 和 DateTimeFormat 对象的构造函数是 Intl 对象的属性。</p>
</blockquote>
<pre><code class="javascript hljs"><span class="hljs-keyword">new <span class="hljs-built_in">Intl.NumberFormat().format(<span class="hljs-number">1234567890) <span class="hljs-comment">// 1,234,567,890</span></span></span></span></code></pre>
<p>优点:简单粗暴,直接调用api</p>
<p>缺点:Intl兼容性不太好,不过 toLocaleString的话 IE6 都支持</p>
<p><strong>前端知识点:Intl对象 和 toLocaleString的方法。</strong></p>
<p>&nbsp;</p>
<p><strong><span style="font-size: large">三、argruments 对象(类数组)转换成数组</span></strong></p>
<p>那什么是类数组?就是跟数组很像,但是他是对象,格式像数组所以叫类数组。比如:{0:a,1:b,2:c,length:3},按照数组下标排序的对象,还有一个length的属性,有时候我们需要这种对象能调用数组下的一个方法,这时候就需要把把类数组转化成真正的数组。</p>
<p><strong>1、普通版</strong></p>
<pre><code class="javascript hljs"><span class="hljs-keyword">var makeArray = <span class="hljs-function"><span class="hljs-keyword">function(<span class="hljs-params">arr){
    <span class="hljs-keyword">var res = [];
    <span class="hljs-keyword">if(arr != <span class="hljs-literal">null){
      <span class="hljs-keyword">var i = arr.length;
      <span class="hljs-keyword">if(i == <span class="hljs-literal">null || <span class="hljs-keyword">typeof arr == <span class="hljs-string">"string") res[<span class="hljs-number">0] = arr;
      <span class="hljs-keyword">else <span class="hljs-keyword">while(i){res[--i] = arr;}
    }
    <span class="hljs-keyword">return res;
};
<span class="hljs-keyword">var obj = {<span class="hljs-number">0:<span class="hljs-string">'a',<span class="hljs-number">1:<span class="hljs-string">'b',<span class="hljs-number">2:<span class="hljs-string">'c',length:<span class="hljs-number">3};
makeArray(obj);</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></code></pre>
<p>优点:通用版本,没有任何兼容性问题<br>缺点:暂时没有啥缺点</p>
<p>&nbsp;</p>
<p><strong>2、进阶版</strong></p>
<pre><code class="javascript hljs"><span class="hljs-comment">// 2、进阶版
<span class="hljs-keyword">var arr = <span class="hljs-built_in">Array.prototype.slice.call(<span class="hljs-built_in">arguments);</span></span></span></span></code></pre>
<p>大家用过最常用的方法,至于为什么可以这么用,很多人估计也是一知半解,要搞清为什么里面的原因,我们还是从规范和源码说起。</p>
<p><strong><code>slice.call</code>&nbsp;的作用原理</strong>就是,利用&nbsp;<code>call</code>,将&nbsp;<code>slice</code>&nbsp;的方法作用于&nbsp;<code>arrayLike</code>,<code>slice</code>&nbsp;的两个参数为空,<code>slice</code>&nbsp;内部解析使得&nbsp;<code>arguments.lengt</code>&nbsp;等于0的时候 相当于处理&nbsp;<code>slice(0)</code>&nbsp;: 即选择整个数组,<code>slice</code>&nbsp;方法内部没有强制判断必须是&nbsp;<code>Array</code>&nbsp;类型,<code>slice</code>&nbsp;返回的是新建的数组(使用循环取值)”,所以这样就实现了类数组到数组的转化,<code>call</code>&nbsp;这个神奇的方法、<code>slice</code>&nbsp;的处理缺一不可。</p>
<p>直接看&nbsp;<code>slice</code>&nbsp;怎么实现的吧。其实就是将&nbsp;<code>array-like</code>&nbsp;对象通过下标操作放进了新的&nbsp;<code>Array</code>&nbsp;里面,下面是源码</p>
<pre><code class="javascript hljs"><span class="hljs-comment">// This will work for genuine arrays, array-like objects,
    <span class="hljs-comment">// NamedNodeMap (attributes, entities, notations),
    <span class="hljs-comment">// NodeList (e.g., getElementsByTagName), HTMLCollection (e.g., childNodes),
    <span class="hljs-comment">// and will not fail on other DOM objects (as do DOM elements in IE &lt; 9)
    <span class="hljs-built_in">Array.prototype.slice = <span class="hljs-function"><span class="hljs-keyword">function(<span class="hljs-params">begin, end) {
      <span class="hljs-comment">// IE &lt; 9 gets unhappy with an undefined end argument
      end = (<span class="hljs-keyword">typeof end !== <span class="hljs-string">'undefined') ? end : <span class="hljs-keyword">this.length;

      <span class="hljs-comment">// For native Array objects, we use the native slice function
      <span class="hljs-keyword">if (<span class="hljs-built_in">Object.prototype.toString.call(<span class="hljs-keyword">this) === <span class="hljs-string">''){
      <span class="hljs-keyword">return _slice.call(<span class="hljs-keyword">this, begin, end);
      }

      <span class="hljs-comment">// For array like object we handle it ourselves.
      <span class="hljs-keyword">var i, cloned = [],
      size, len = <span class="hljs-keyword">this.length;

      <span class="hljs-comment">// Handle negative value for "begin"
      <span class="hljs-keyword">var start = begin || <span class="hljs-number">0;
      start = (start &gt;= <span class="hljs-number">0) ? start : <span class="hljs-built_in">Math.max(<span class="hljs-number">0, len + start);

      <span class="hljs-comment">// Handle negative value for "end"
      <span class="hljs-keyword">var upTo = (<span class="hljs-keyword">typeof end == <span class="hljs-string">'number') ? <span class="hljs-built_in">Math.min(end, len) : len;
      <span class="hljs-keyword">if (end &lt; <span class="hljs-number">0) {
      upTo = len + end;
      }
      <span class="hljs-comment">// Actual expected size of the slice
      size = upTo - start;
      <span class="hljs-keyword">if (size &gt; <span class="hljs-number">0) {
      cloned = <span class="hljs-keyword">new <span class="hljs-built_in">Array(size);
      <span class="hljs-keyword">if (<span class="hljs-keyword">this.charAt) {
          <span class="hljs-keyword">for (i = <span class="hljs-number">0; i &lt; size; i++) {
            cloned = <span class="hljs-keyword">this.charAt(start + i);
          }
      } <span class="hljs-keyword">else {
          <span class="hljs-keyword">for (i = <span class="hljs-number">0; i &lt; size; i++) {
            cloned = <span class="hljs-keyword">this;
          }
      }
      }

      <span class="hljs-keyword">return cloned;
    };</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></code></pre>
<p>优点:最常用的版本,兼容性强。</p>
<p>缺点:ie 低版本,无法处理 dom 集合的 slice call 转数组。</p>
<p>&nbsp;</p>
<p><strong>3、ES6版</strong></p>
<p>使用&nbsp;<code>Array.from</code>, 值需要对象有&nbsp;<code>length</code>&nbsp;属性, 就可以转换成数组。</p>
<pre><code class="javascript hljs"><span class="hljs-keyword">var arr = <span class="hljs-built_in">Array.from(<span class="hljs-built_in">arguments);</span></span></span></code></pre>
<p>扩展运算符</p>
<pre><code class="javascript hljs"><span class="hljs-keyword">var args = [...arguments];</span></code></pre>
<p><code>ES6</code>&nbsp;中的扩展运算符...也能将某些数据结构转换成数组,这种数据结构必须有便利器接口。</p>
<p>优点:直接使用内置 API,简单易维护<br>缺点:兼容性,使用 babel 的 profill 转化可能使代码变多,文件包变大</p>
<p><strong>前端知识点:slice 方法的具体原理</strong></p>
<p>&nbsp;</p>
<blockquote>
<p>【注:我是saucxs,也叫songEagle,松宝写代码,文章首发于sau交流学习社区(https://www.mwcxs.top),关注我们每天阅读更多精彩内容】</p>
<p>&nbsp;</p>

</blockquote>

</div>
<div id="MySignature" role="contentinfo">
    文中有错误的地方希望指出,共同进步<br><br>
来源:https://www.cnblogs.com/chengxs/p/10955182.html
頁: [1]
查看完整版本: JavaScript 系列--JavaScript一些奇淫技巧的实现方法(二)数字格式化 1234567890转1,234,567,890;argruments 对象(类数组)转换成数组