<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>岁月如歌 &#187; array</title>
	<atom:link href="http://lifesinger.org/blog/tag/array/feed/" rel="self" type="application/rss+xml" />
	<link>http://lifesinger.org/blog</link>
	<description>关注用户体验、前端开发，记录生活点滴、岁月足迹。</description>
	<lastBuildDate>Wed, 28 Jul 2010 00:40:47 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
		<item>
		<title>Array.prototype.slice</title>
		<link>http://lifesinger.org/blog/2010/05/array-prototype-slice/</link>
		<comments>http://lifesinger.org/blog/2010/05/array-prototype-slice/#comments</comments>
		<pubDate>Tue, 04 May 2010 01:32:31 +0000</pubDate>
		<dc:creator>lifesinger</dc:creator>
				<category><![CDATA[开发]]></category>
		<category><![CDATA[array]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[slice]]></category>

		<guid isPermaLink="false">http://lifesinger.org/blog/?p=2581</guid>
		<description><![CDATA[slice 可以用来获取数组片段，它返回新数组，不会修改原数组。 除了正常用法，slice 经常用来将 array-like 对象转换为 true array. 名词解释：array-like object &#8211; 拥有 length 属性的对象，比如 { 0: &#8216;foo&#8217;, length: 1 }, 甚至 { length: &#8216;bar&#8217; }. 最常见的 array-like 对象是 arguments 和 NodeList. 查看 V8 引擎 array.js 的源码，可以将 slice 的内部实现简化为： function slice(start, end) { var len = ToUint32(this.length), result = []; for(var i = start; i < [...]]]></description>
			<content:encoded><![CDATA[<p>slice 可以用来获取数组片段，它返回新数组，不会修改原数组。</p>
<p>除了正常用法，slice 经常用来将 array-like 对象转换为 true array.</p>
<p>名词解释：array-like object &#8211; 拥有 length 属性的对象，比如 { 0: &#8216;foo&#8217;, length: 1 }, 甚至 { length: &#8216;bar&#8217; }. 最常见的 array-like 对象是 arguments 和 NodeList.</p>
<p>查看 V8 引擎<a href="http://www.google.com/codesearch/p?hl=en#W9JxUuHYyMg/trunk/src/array.js"> array.js</a> 的源码，可以将 slice 的内部实现简化为：</p>
<pre>
function slice(start, end) {
    var len = ToUint32(this.length), result = [];
    for(var i = start; i < end; i++) {
        result.push(this[i]);
    }
    return result;
}
</pre>
<p>可以看出，slice 并不需要 this 为 array 类型，只需要有 length 属性即可。并且 length 属性可以不为 number 类型，当不能转换为数值时，ToUnit32(this.length) 返回 0.<br />
<span id="more-2581"></span><br />
对于标准浏览器，上面已经将 slice 的原理解释清楚了。但是恼人的 ie, 总是给我们添乱子：</p>
<pre>
var slice = Array.prototype.slice;
slice.call(); // => IE: Object expected.
slice.call(document.childNodes); // => IE: JScript object expected.
</pre>
<p>以上代码，在 ie 里报错。可恨 IE 的 Trident 引擎不开源，那我们只有猜测了：</p>
<pre>
function ie_slice(start, end) {
    var len = ToUint32(this.length), result = [];

    if(__typeof__ this !== 'JScript Object') throw 'JScript object expected';
    if(this === null) throw 'Oject expected';

    for(var i = start; i < end; i++) {
        result.push(this[i]);
    }
    return result;
}
</pre>
<p>至此，把猥琐的 ie 自圆其说完毕。</p>
<p>关于 slice, 还有一个话题：用 Array.prototype.slice 还是 [].slice ? 从理论上讲，[] 需要创建一个数组，性能上会比 Array.prototype 稍差。但实际上，这两者差不多，就如循环里用 i++ 还是 ++i 一样，纯属个人习惯。</p>
<p>最后一个话题，有关性能。对于数组的筛选来说，有一个牺牲色相的写法：</p>
<pre>
var ret = [];
for(var i = start, j = 0; i < end; i++) {
    ret[j++] = arr[i];
}
</pre>
<p>用空间换时间。去掉 push, 对于大数组来说，性能提升还是比较明显的。</p>
<p>一大早写博，心情不是很好，得留个题目给大家：</p>
<pre>
var slice = Array.prototype.slice;
alert(slice.call({0: 'foo', length: 'bar'})[0]); // ?
alert(slice.call(NaN).length); // ?
alert(slice.call({0: 'foo', length: '100'})[0]); // ?
</pre>
]]></content:encoded>
			<wfw:commentRss>http://lifesinger.org/blog/2010/05/array-prototype-slice/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>Chrome V8 引擎对 sort 的优化</title>
		<link>http://lifesinger.org/blog/2010/02/chrome-v8-optimization-for-sort/</link>
		<comments>http://lifesinger.org/blog/2010/02/chrome-v8-optimization-for-sort/#comments</comments>
		<pubDate>Wed, 03 Feb 2010 04:25:15 +0000</pubDate>
		<dc:creator>lifesinger</dc:creator>
				<category><![CDATA[开发]]></category>
		<category><![CDATA[array]]></category>
		<category><![CDATA[chrome]]></category>
		<category><![CDATA[sort]]></category>
		<category><![CDATA[v8]]></category>

		<guid isPermaLink="false">http://lifesinger.org/blog/?p=2431</guid>
		<description><![CDATA[var a = 0, b = 0; [0, 0].sort(function() { a = 1; return 0; }); [0, 1].sort(function() { b = 1; return 0; }); alert(a === b); // true or false ? 上面的代码，除了 Chrome 输出 false, 其它浏览器皆为 true. 原因是 Chrome 对数组的 sort 方法进行了优化： function sort(comparefn) { var custom_compare = (typeof(comparefn) === 'function'); function Compare(x,y) [...]]]></description>
			<content:encoded><![CDATA[<pre>
var a = 0, b = 0;
[0, 0].sort(function() {
    a = 1;
    return 0;
});
[0, 1].sort(function() {
    b = 1;
    return 0;
});
alert(a === b); // true or false ?
</pre>
<p>上面的代码，除了 Chrome 输出 false, 其它浏览器皆为 true.</p>
<p>原因是 Chrome 对数组的 sort 方法进行了优化：</p>
<pre>
function sort(comparefn) {
  var custom_compare = (typeof(comparefn) === 'function');
  function Compare(x,y) {
    if (x === y) return 0;
    if (custom_compare) {
      return comparefn.call(null, x, y);
    }
    ...
}
</pre>
<p>虽然是优化，但也是陷阱。想用 sort 来干点额外体力活时，一定要小心。</p>
]]></content:encoded>
			<wfw:commentRss>http://lifesinger.org/blog/2010/02/chrome-v8-optimization-for-sort/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<item>
		<title>小心数组的length</title>
		<link>http://lifesinger.org/blog/2009/01/be-careful-about-array-length/</link>
		<comments>http://lifesinger.org/blog/2009/01/be-careful-about-array-length/#comments</comments>
		<pubDate>Fri, 23 Jan 2009 17:32:18 +0000</pubDate>
		<dc:creator>lifesinger</dc:creator>
				<category><![CDATA[开发]]></category>
		<category><![CDATA[array]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[length]]></category>

		<guid isPermaLink="false">http://lifesinger.org/blog/?p=1024</guid>
		<description><![CDATA[看下面的代码： var foo = []; foo[0] = 'a'; foo[2] = 'c'; alert(foo.length); foo['name'] = 'lifesinger'; alert(foo.length); var foo2 = []; foo2['3'] = 3; foo2['age'] = 20; alert(foo2.length); var foo3 = {}; foo3['age'] = 30; alert(foo3.length); 对alert的输出结果是否感到有点惊讶？从上面的代码中，我们可以总结出以下规律： 对普通数组（key为自然数，从0开始依次增大1）来说，length是预期的结果 对关联数组来说，当key中有自然数时，length等于key中的最大自然数 + 1, key中没有自然数时，length为0 对象默认是没有length属性的 小心length, 别掉进代码的陷阱里。 更新： JavaScript没有关联数组，key/value pair直接是对象提供的。感谢realazy指点。 对于key中含有非自然数的数组，可以分成两部分来看：一部分是数组本身的键值对，另一部分是对象的属性。length是针对数组部分而言的，因此始终等于 0 或 key中的最大自然数 + 1.]]></description>
			<content:encoded><![CDATA[<p>看下面的代码：</p>
<pre>
var foo = [];
foo[0] = 'a';
foo[2] = 'c';
alert(foo.length);

foo['name'] = 'lifesinger';
alert(foo.length);

var foo2 = [];
foo2['3'] = 3;
foo2['age'] = 20;
alert(foo2.length);

var foo3 = {};
foo3['age'] = 30;
alert(foo3.length);
</pre>
<p>对alert的输出结果是否感到有点惊讶？从上面的代码中，我们可以总结<span id="more-1024"></span>出以下规律：</p>
<ol>
<li>对普通数组（key为自然数，从0开始依次增大1）来说，length是预期的结果</li>
<li>对关联数组来说，当key中有自然数时，length等于key中的最大自然数 + 1, key中没有自然数时，length为0</li>
<li>对象默认是没有length属性的</li>
</ol>
<p>小心length, 别掉进代码的陷阱里。</p>
<p><strong>更新：</strong></p>
<ol>
<li>JavaScript没有关联数组，key/value pair直接是对象提供的。感谢realazy指点。</li>
<li>对于key中含有非自然数的数组，可以分成两部分来看：一部分是数组本身的键值对，另一部分是对象的属性。length是针对数组部分而言的，因此始终等于 0 或 key中的最大自然数 + 1.</li>
]]></content:encoded>
			<wfw:commentRss>http://lifesinger.org/blog/2009/01/be-careful-about-array-length/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
	</channel>
</rss>
