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 --> 1,234,567,890</p>
<p> </p>
<p><strong><span style="font-size: large">二、数字格式化 1234567890 --> 1,234,567,890</span></strong></p>
<p><strong>1、普通版</strong></p>
<pre><code class="javascript hljs"><span class="hljs-comment">// 数字格式化 1234567890 --> 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>=<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 && 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> </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) => {
<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> </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> </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>你可能还不知道 <code>JavaScript</code> 的 <code>toLocaleString</code> 还可以这么玩。</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> </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> </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> 的作用原理</strong>就是,利用 <code>call</code>,将 <code>slice</code> 的方法作用于 <code>arrayLike</code>,<code>slice</code> 的两个参数为空,<code>slice</code> 内部解析使得 <code>arguments.lengt</code> 等于0的时候 相当于处理 <code>slice(0)</code> : 即选择整个数组,<code>slice</code> 方法内部没有强制判断必须是 <code>Array</code> 类型,<code>slice</code> 返回的是新建的数组(使用循环取值)”,所以这样就实现了类数组到数组的转化,<code>call</code> 这个神奇的方法、<code>slice</code> 的处理缺一不可。</p>
<p>直接看 <code>slice</code> 怎么实现的吧。其实就是将 <code>array-like</code> 对象通过下标操作放进了新的 <code>Array</code> 里面,下面是源码</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 < 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 < 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 >= <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 < <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 > <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 < 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 < 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> </p>
<p><strong>3、ES6版</strong></p>
<p>使用 <code>Array.from</code>, 值需要对象有 <code>length</code> 属性, 就可以转换成数组。</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> 中的扩展运算符...也能将某些数据结构转换成数组,这种数据结构必须有便利器接口。</p>
<p>优点:直接使用内置 API,简单易维护<br>缺点:兼容性,使用 babel 的 profill 转化可能使代码变多,文件包变大</p>
<p><strong>前端知识点:slice 方法的具体原理</strong></p>
<p> </p>
<blockquote>
<p>【注:我是saucxs,也叫songEagle,松宝写代码,文章首发于sau交流学习社区(https://www.mwcxs.top),关注我们每天阅读更多精彩内容】</p>
<p> </p>
</blockquote>
</div>
<div id="MySignature" role="contentinfo">
文中有错误的地方希望指出,共同进步<br><br>
来源:https://www.cnblogs.com/chengxs/p/10955182.html
頁:
[1]