JavaScript/Notes/Array: Difference between revisions

From Noisebridge
Jump to navigation Jump to search
(Created page with " Array methods are used or hand-rolled (as a fallback in a lot of javascript libraries, such as jQuery and Underscore, as discussed tonight. EcmaScript 5 has standardized me...")
 
 
(30 intermediate revisions by the same user not shown)
Line 1: Line 1:
In this lesson, I explain what an <code>Array</code> is, properties of Array instances, and methods of <code>Array.prototype</code> that were added in EcmaScript 5.
== What is an Array ==
Array instances also have a special definition for the internal method called <code><nowiki>[[DefineOwnProperty]] ( P, Desc, Throw )</nowiki></code> used for property assignment and a special <code>length</code> property that affects and is affected by the properties in the array. The <code><nowiki>[[Class]]</nowiki></code> internal property value is "Array" ([http://www.ecma-international.org/ecma-262/5.1/#sec-15.4.5 &sect; 15.4.5]).


Arrays are Objects. Array instances inherit properties from the <code>Array prototype</code> ([http://www.ecma-international.org/ecma-262/5.1/#sec-15.4.4 &sect;15.4.4]) object and Array.prototype inherits properties from Object.prototype.
=== Length and <nowiki>[[DefineOwnProperty]]</nowiki> ===
<source lang="javascript">
// length.
var a = ["a", "b" , "c", undefined];
"3" in a; // true;
a[3]; // undefined;
a.length = 2;
"2" in a; // false.


Array methods are used or hand-rolled (as a fallback in a lot of javascript libraries, such as jQuery and Underscore, as discussed tonight.
// DefineOwnProperty
a[4] = "CC";
a.length; // 5;
"3" in a; // true.
a[3]; // undefined.


EcmaScript 5 has standardized methods that were introduced as "Array Extras" in Firefox 1.5. These neat methods are present in all modern browsers, but can have a noticeable performance impact for lengthy arrays, particularly on limited devices.
// Sparse array DO NOT DO THIS.
delete a[2]; // true
"2" in a; // false
</source>


The normative reference for these methods is the EcmaScript 5.1 specification, a mature, official standard. Each method description has an overview of what it does, followed by the algorithm.
== NodeLists Are Not Arrays ==
There are many collections in the DOM that have indexed properties but are not Arrays. NodeList is one such example. For example,  
<source lang="javascript">
document.getElementsByTagName("div");
</source>
&mdash; returns a live collection.  


In modern browsers Array methods can be used generically on these Array-like host objects. For example:
<source lang="javascript">
var slice = Array.prototype.slice;
var divs = document.getElementsByTagName("div");
divArray = slice.call(divs); // create a new Array
function filterOutEmptyDivs(el) {
// Using ES5 String.prototype.trim; assuming textContent is supported.
  return el.getElementsByTagName("*").length > 0 && !el.textContent.trim();
}
divArray.filter(filterOutEmptyDivs);
</source>
However, IE8 and below will throw an error when slice is called on a Host object. See also:
* [http://www.ecma-international.org/ecma-262/5.1/#sec-15.4.4.10 Array.prototype.slice (start, end)]
* [http://lists.w3.org/Archives/Public/public-webapps/2008JulSep/0480.html Re: [whatwg] WebIDL and HTML5]
* [https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/slice Slice:MDN]
* [http://www.jibbering.com/faq/#hostObject What is a Host Object?]
== EcmaScript 5 Array Methods ==
The normative reference for Array is the EcmaScript 5.1 specification, a mature, official standard. See [http://www.ecma-international.org/ecma-262/5.1/#sec-15.4.4 &sect;15.4 Array].
EcmaScript 5 formally standardized the "Array Extras" that were previously introduced in Firefox 1.5 (Mozilla JavaScript&trade; 1.6) in 2006.
These added methods are present in common modern browsers, but can have a noticeable performance impact for lengthy arrays, particularly on limited devices, and especially with large data sets.
<source lang="javascript">
Array.prototype.indexOf
Array.prototype.indexOf
Array.prototype.lastIndexOf
Array.prototype.lastIndexOf
Line 16: Line 70:
Array.prototype.reduce
Array.prototype.reduce
Array.prototype.reduceRight
Array.prototype.reduceRight
</source>


Here is the link to Array.prototype:
Each method description has an overview of what it does, followed by the algorithm. The complete list of methods is to be found in the EcmaScript specification. See [http://www.ecma-international.org/ecma-262/5.1/#sec-15.4.4 Array.prototype].
http://www.ecma-international.org/ecma-262/5.1/#sec-15.4.4


MDC on Array:
[https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array MDC Array]
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array


It is interesting that these methods can also be used generically on something that is Array-like.
It is interesting that these methods can also be used generically on something that is Array-like.
 
<source lang="javascript">
var filter = Array.prototype.filter;
var filter = Array.prototype.filter;


filter.call("foo",  function (ch) { return ch == "o"; }).join("");
filter.call("foo",  function (ch) { return ch == "o"; }).join("");
</source>


Array-like was proposed as a standard interface (I championed this idea for a while), but was not included. Perhaps it will be, some day.
Array-like was proposed as a standard interface (I championed this idea for a while), but was not included. Perhaps it will be, some day.
Line 33: Line 87:
But for now, it is useful to know that these methods are natively supported in modern browsers.
But for now, it is useful to know that these methods are natively supported in modern browsers.


In a few weeks from now, I will be teaching a class on javascript to delve into a deeper understanding of the EcmaScript programming language itself, as well as coding strategies and reuse patterns.
== Assignment 1 Write a function that removes an element from an array. ==
Write a function that that takes an array and a specified element, and returns the array, minus the first occurence of the element from the array.
 
Given:
<source lang="javascript">
var thing = {}, f = function(){};
var input = [f, [], /foo/, thing, []];
 
removeElement(input, thing); //  [f, [], /foo/, []];
</source>
 
<!--
 
// YAGNI.
a.splice(a.indexOf(x), 1);
 
// Returns the same array.
function removeElement(a, x) {
  a.splice(a.indexOf(x), 1);
  return a;
}
 
// returns a new array.
function removeElement(a, x) {
  var i = a.indexOf(x);
  if(x != -1 && a.length > 0) {
    var r = a.slice(0, i).concat(a.slice(i));
  } else {
    r = []; return r;
  }
}
-->
 
== Assignment 2 Write a function that removes duplicate numbers from an array. ==
<source lang="javascript">
var input = [1, 2, 3, 1, 0, 1];
var result = arrayUniqueNumbers( input ); // [1, 2, 3, 0];
</source>
 
<!--
function arrayUnique( input ) {
    var ret = [], j = 0, obj = {};
    for(var i = 0; i < input.length; i++) {
        var x = input[i]; if(x in obj) continue;
        obj[x] = true; ret[j++] = x; } return ret;
    }
}
-->
 
== Assignment 3 Write a function that sorts an array of strings case-insensitively. ==
Write a function that sorts an array of strings case-insensitively.
<source lang="javascript">
var input = ["penguin", "Beard", "pelican", "bear", "ostrich"];
sortStringsCI(input); // ["Bear", "pelican", "penguin", "ostrich"];
</source>
 
<!--
function sortStringsCI(a, b) {
    return a.toLowerCase() > b.toLowerCase();
}
-->

Latest revision as of 12:49, 7 January 2014

In this lesson, I explain what an Array is, properties of Array instances, and methods of Array.prototype that were added in EcmaScript 5.

What is an Array[edit]

Array instances also have a special definition for the internal method called [[DefineOwnProperty]] ( P, Desc, Throw ) used for property assignment and a special length property that affects and is affected by the properties in the array. The [[Class]] internal property value is "Array" (§ 15.4.5).

Arrays are Objects. Array instances inherit properties from the Array prototype (§15.4.4) object and Array.prototype inherits properties from Object.prototype.

Length and [[DefineOwnProperty]][edit]

<source lang="javascript"> // length. var a = ["a", "b" , "c", undefined]; "3" in a; // true; a[3]; // undefined; a.length = 2; "2" in a; // false.

// DefineOwnProperty a[4] = "CC"; a.length; // 5; "3" in a; // true. a[3]; // undefined.

// Sparse array DO NOT DO THIS. delete a[2]; // true "2" in a; // false </source>

NodeLists Are Not Arrays[edit]

There are many collections in the DOM that have indexed properties but are not Arrays. NodeList is one such example. For example, <source lang="javascript"> document.getElementsByTagName("div"); </source> — returns a live collection.

In modern browsers Array methods can be used generically on these Array-like host objects. For example:

<source lang="javascript"> var slice = Array.prototype.slice;

var divs = document.getElementsByTagName("div"); divArray = slice.call(divs); // create a new Array

function filterOutEmptyDivs(el) { // Using ES5 String.prototype.trim; assuming textContent is supported.

 return el.getElementsByTagName("*").length > 0 && !el.textContent.trim();

}

divArray.filter(filterOutEmptyDivs); </source>

However, IE8 and below will throw an error when slice is called on a Host object. See also:

EcmaScript 5 Array Methods[edit]

The normative reference for Array is the EcmaScript 5.1 specification, a mature, official standard. See §15.4 Array.

EcmaScript 5 formally standardized the "Array Extras" that were previously introduced in Firefox 1.5 (Mozilla JavaScript™ 1.6) in 2006.

These added methods are present in common modern browsers, but can have a noticeable performance impact for lengthy arrays, particularly on limited devices, and especially with large data sets.

<source lang="javascript"> Array.prototype.indexOf Array.prototype.lastIndexOf Array.prototype.every Array.prototype.some Array.prototype.forEach Array.prototype.map Array.prototype.filter Array.prototype.reduce Array.prototype.reduceRight </source>

Each method description has an overview of what it does, followed by the algorithm. The complete list of methods is to be found in the EcmaScript specification. See Array.prototype.

MDC Array

It is interesting that these methods can also be used generically on something that is Array-like. <source lang="javascript"> var filter = Array.prototype.filter;

filter.call("foo", function (ch) { return ch == "o"; }).join(""); </source>

Array-like was proposed as a standard interface (I championed this idea for a while), but was not included. Perhaps it will be, some day.

But for now, it is useful to know that these methods are natively supported in modern browsers.

Assignment 1 Write a function that removes an element from an array.[edit]

Write a function that that takes an array and a specified element, and returns the array, minus the first occurence of the element from the array.

Given: <source lang="javascript"> var thing = {}, f = function(){}; var input = [f, [], /foo/, thing, []];

removeElement(input, thing); // [f, [], /foo/, []]; </source>


Assignment 2 Write a function that removes duplicate numbers from an array.[edit]

<source lang="javascript"> var input = [1, 2, 3, 1, 0, 1]; var result = arrayUniqueNumbers( input ); // [1, 2, 3, 0]; </source>


Assignment 3 Write a function that sorts an array of strings case-insensitively.[edit]

Write a function that sorts an array of strings case-insensitively. <source lang="javascript"> var input = ["penguin", "Beard", "pelican", "bear", "ostrich"]; sortStringsCI(input); // ["Bear", "pelican", "penguin", "ostrich"]; </source>