この記事では、JavaScript の参照型に関する知識を含む、オブジェクトおよび配列の参照型に関する JavaScript の高度なプログラミングの学習メモを共有します。見てみましょう。
1. オブジェクトの種類
ほとんどの参照型の値は Object 型のインスタンスであり、Object は ECMAScript で最も一般的に使用される型でもあります。
オブジェクト インスタンスを作成するには 2 つの方法があります:
新しい演算子の後にオブジェクト コンストラクターが続きます:
var person=new Object( ); person.name="webb"; person.age=25;
オブジェクトリテラル表記:
var person={ name:"webb", age:25 };
2. 配列型
Object に加えて、Array 型はおそらく ECMAScript で最もよく使用される型です。
ECMAScript 配列の各項目は、任意のタイプのデータを保持できます (たとえば、最初の位置に文字列、2 番目の位置に値、3 番目の位置にオブジェクトなどを格納できます)。さらに、ECMAScript 配列のサイズは動的に調整できます。つまり、新しいデータに対応するためにデータが追加されると自動的に拡張できます。
配列を作成するには 2 つの基本的な方法があります。
配列コンストラクターを使用します:
var colors=new Array( ); var colors=new Array(20); //也可设置length属性 var colors=new Array("red","blue","green"); //包含3个字符串的数组 var colors=Array(3); //可省略new操作符
配列リテラル表記
var colors=["red","blue","green"]; alert(colors[0]); //显示第一项 colors[2]="black"; //修改第三项 colors[3]="brown"; //新增第四项
注: 配列の長さプロパティは非常に特殊であり、読み取り専用ではありません。したがって、このプロパティを設定すると、配列の末尾から項目を削除または追加できます。たとえば、
var colors=["red","blue","green"]; colors.length=2; alert(colors[2]); //undefined colors[colors.length]="black"; //在末尾添加项
2.1 検出アレイ
Web ページまたはグローバル スコープの場合、instanceof 演算子を使用して、オブジェクトが配列であるかどうかを判断できます。
if(value instanceof Array){ //对数组执行某些操作 }
instanceof 演算子の問題は、グローバル実行環境が 1 つだけ存在すると想定していることです。 Web ページに複数のフレームが含まれている場合、実際には 3 つ以上の異なるグローバル実行環境が存在し、したがって 3 つ以上の異なるバージョンの Array コンストラクターが存在します。あるフレームから別のフレームに配列を渡す場合、渡す配列には、2 番目のフレームでネイティブに作成された配列とは異なるコンストラクターが含まれます。
この問題を解決するために、ECMAScript5 は Array.isArray() メソッドを追加しました。このメソッドの目的は、値が作成されたグローバル実行環境に関係なく、値が配列であるかどうかを最終的に判断することです。
if(Array.isArray(value)){ //对数组执行某些操作 }
この方法をサポートするブラウザには、IE9、Firefox 4、Safari 5、Opera 10.5、Chrome などがあります。
2.2 変換方法
配列の toString() メソッドを呼び出すと、配列内の各値の文字列形式を連結したカンマ区切りの文字列が返されます。 valueOf() を呼び出しても配列が返されます。実際、この文字列を作成するには、配列内の各項目の toString() メソッドが呼び出されます。たとえば、
var colors=["red","blue","green"]; alert(colors.toString()); //red,blue,green alert(colors.valueOf()); //red,blue,green alert(colors); //red,blue,green
さらに、toLocaleString() メソッドは、toString() および valueOf() メソッドと同じ値を返すことがよくありますが、常にそうとは限りません。配列の toLocaleString() メソッドが呼び出されると、配列値のカンマ区切り文字列も作成されます。最初の 2 つのメソッドとの唯一の違いは、今回は各項目の値を取得するために、toString() メソッドの代わりに各項目の toLocaleString() メソッドが呼び出されることです。
var person1={ toLocaleString:function(){ return "webbxx"; }, toString:function(){ return "webb"; } }; var person2={ toLocaleString:function(){ return "susanxx"; }, toString:function(){ return "susan"; } }; var people=[person1,person2]; alert(people); //webb,susan alert(people.toString()); //webb,susan alert(people.toLocaleString()); //webbxx,susanxx 使用join( )方法也可输出数组,并可指定分隔符,默认为逗号: var colors=["red","blue","green"]; alert(colors.join(",")); //red,blue,green alert(colors.join("||")); //red||blue||green
2.3 スタックメソッド (LIFO)
Push(): 任意の数のパラメータを受け取り、それらを配列の末尾に 1 つずつ追加し、変更された配列の長さを返します。
Pop(): 配列の末尾から最後の項目を削除します
var colors=new Array(); var count=colors.push("red","green"); alert(count); //2 count=colors.push("black"); alert(count); //3 var item=colors.pop(); alert(item); //"black" alert(colors.length); //2
2.4 队列方法(FIFO)
shift( ):移除数组的第一项并返回该项,同时数组长度减1;
unshift( ):顾名思义,与shift( )用途相反,能在数组前端添加任意个项并返回数组的长度。
2.5 重排序方法
reverse( ):反转数组项的顺序;
sort( ):默认按升序排列;为了实现排序,sort( )方法会调用每项的toString( )方法,然后比较得到的字符串,以确定如何排序。即使每一项都是数值,比较的也是字符串,如下所示。
var values=[0,1,5,10,15]; values.sort(); alert(values); //0,1,10,15,5
这种排序方式在很多情况下都不是最佳方案。因此sort( )方法可以接受一个比较函数作为参数,以便指定哪个值位于哪个值的前面。
function compare(value1,value2){ if(value1<value2){ return -1; //value1在value2之前 }else if(value1>value2){ return 1; }else{ return 0; } }
这个比较函数可以适用大多数据类型,只要将其作为参数传递给sort( )方法即可,如下,
var values=[0,1,5,10,15]; values.sort(compare); alert(values); //0,1,5,10,15
2.6 操作方法
concat( ):基于当前数组中的所有项创建一个新数组。例如,
var colors=["red","blue","green"]; var colors2=colors.concat("yellow",["black","brown"]); alert(colors); //red,blue,green alert(colors2); //red,blue,green,yellow,black,brown
slice( ):基于当前数组中的一个或多个项创建一个新数组。例如,
var colors=["red","green","blue","yellow","purple"]; var colors2=colors.slice(1); //green,blue,yellow,purple var colors3=colors.slice(1,3); //green,blue,yellow
splice( ):这个方法恐怕是最强大的数组方法了,主要用途是向数组的中部插入项,但使用这种方法的方式则有如下2种。
删除:可以删除任意数量的项,只需指定2个参数:要删除的第一项的位置和要删除的项数。
插入:可以向指定位置插入任意数量的项,只需提供3个参数:起始位置、0(要删除的项数)和要插入的项。如果要插入多个项,可以再传第四、第五以至任意多个项;例如,splice(2,0,"red","green")会从当前数组的位置2开始插入字符串"red"和"green"。
splice( )方法始终都会返回一个数组,包含从原始数组中删除的项(如果没有删除任何项,则返回空数组)。
2.7 位置方法
indexOf( )和lastIndexOf( ):这两个方法都接受两个参数:要查找的项和(可选的)表示查找起点位置的索引。前者从开头开始向后查找,后者从末尾向前查找
2.8 迭代方法
ECMAScript5为数组定义了5个迭代方法,每个方法都接受两个参数:要在每一项上运行的函数和(可选的)运行该函数的作用域对象——影响this的值。传入这些方法中的函数会接收三个参数:数组项的值、该项在数组中的位置和数组对象本身。
every( ):对数组中的每一项运行给定函数,如果该函数对每一项都返回true,则返回true。
filter( ):对数组中的每一项运行给定函数,返回该函数会返回true的项组成的数组。
forEach( ):对数组中的每一项运行给定函数,这个方法无返回值。
map( ):对数组中的每一项运行给定函数,返回每次函数调用的结果组成的数组。
some( ):对数组中的每一项运行给定函数,如果该函数对任一项返回true,则返回true。
以上方法都不会修改数组中包含的值。例如,
var numbers=[1,2,3,4,5,4,3,2,1]; var everyResult=numbers.every(function(item,index,array){ return item>2; }); alert(everyResult); //false var someResult=numbers.every(function(item,index,array){ return item>2; }); alert(someResult); //true var filterResult=numbers.every(function(item,index,array){ return item>2; }); alert(filterResult); //[3,4,5,4,3] var mapResult=numbers.every(function(item,index,array){ return item*2; }); alert(mapResult); //[2,4,6,8,10,8,6,4,2]
2.9 归并方法
reduce( ):从数组的第一项开始,逐个遍历到最后;
reduceRight( ):从数组的最后一项开始,向前遍历到第一项。
这两个方法都接受两个参数:一个在每一项上调用的函数和(可选的)作为归并基础的初始值。传给这些方法的函数接受4个参数:前一个值、当前值、项的索引和数组对象。这个函数返回的任何值都会作为第一个参数传给下一项。例如,
var values=[1,2,3,4,5]; var sum=values.reduce(function(prev,cur,index,array){ return prev+cur; }); alert(sum); //15