この記事では、objectのような配列を介したjavascriptの長さ属性の秘密をいくつか探ります。 例 1:
var obj={0:'a',1:'b'} alert(obj.length); //undefined var arr=['a','b'] alert(arr.length); // 2
上記の例から、配列状のオブジェクトの長さ属性は、格納されるデータ量に直接関係していません。インデックス属性 (0, 1) と長さ属性は両方とも考慮されます。オブジェクトの通常の属性の間には関係はありません。js エンジンは、格納されたデータの量に基づいて配列のようなオブジェクトの長さを自動的に計算しません。
しかし、配列のようなオブジェクトの長さは、保存されるデータの量と本当に何の関係もないのでしょうか?例 2 は、これが当てはまらないことを示しています。例 2:
function myarr(){} var m=new myarr(); Array.prototype.push.apply(m,['cson','lai','xiaoc']); alert(m.length);//IE8以下:undefined 其他浏览器:3 alert(m[2]);//IE8以下:undefined 其他浏览器:‘xiaoc'
この例では、例 2 の myarr
constructor
に初期化操作を追加し、配列のようなオブジェクトが初期化されるときに要素を追加します。配列メソッドの強制使用をサポートします。これについては次の例で説明します。他のブラウザの場合、長さ属性の出力は 3 で、インデックス 2 の要素は 'xiaoc' ですが、明らかに、JS エンジンは配列のようなオブジェクトにもともと存在していたインデックス 0 の要素 'cc' を完全に無視します。次の例を見てみましょう。この例では、例 3 に基づいて length 属性に追加の初期化を追加します。 function myarr(){this[0]='cc';}
var m=new myarr();
Array.prototype.push.apply(m,['cson','lai','xiaoc']);
alert(m.length);//ie8以下:undefined 其他:3
alert(m[2]);//ie8以下:undefined 其他:xiaoc
ここで、長さ属性を不正な型に初期化してみます:
function myarr(){this[0]='cc'; this.length=1;}//多加一个length的初始化 var m=new myarr(); Array.prototype.push.apply(m,['cson','lai','xiaoc']); alert(m.length);//输出4 alert(m[2]);//输出'lai‘
function myarr(){this[0]='cc'; this.length="bo";}//length设置为不能转换为number的不合法类型 var m=new myarr(); Array.prototype.push.apply(m,['cson','lai','xiaoc']); alert(m.length);//输出 3 alert(m[2]);// 输出'xiaoc‘
IE6 7:
IE6 7 では要素を追加するために配列メソッドの使用を強制しませんが、最初に length 属性が存在するかどうかを判断し、存在しない場合は返されません。あらゆる操作を行っています。長さ属性が不正な値の場合は、数値型への変換を試みます。変換が失敗すると、長さは 0 に設定されます。これにより、例 2 と 3 の未定義の出力と、例 4 の正しい出力が解析されます。
他のブラウザは、長さ属性に基づいて異なる操作を実行します。長さ属性が存在しない場合は、長さを 0 に設定します。長さ属性が不正な値の場合は、数値型への変換を試みます。変換が失敗した場合、長さも 0 に設定されます。
長さ属性は配列メソッドにおいて非常に決定的な役割を果たすため、JS エンジンは長さ属性に不正な値を書き込むことを禁止します:
function myarr(){this[0]='cc'; this.length="1";}//length设置为能转换为数字的不合法类型 Array.prototype.push.apply(m,['cson','lai','xiaoc']); alert(m.length);//输出4 alert(m[2]);//输出'lai‘
var arr=['1','2','3']; arr.length='undefined';//报错invalid array length
プロトタイプ
inheritance
配列を使用する場合、要素の数に関係なく、IE 6 および 7 では長さは常に 0 になります。ブラウザは普通です。
長さ属性が強制的に設定されたとしても、IE6 7 では常に 0 になります:
function myarr(){} myarr.prototype=new Array(); var m=new myarr(); m.push('cson','lai','xiaoc'); alert(m.length);//IE6 7:0 其他:3 alert(m[2]);//所有浏览器:'xiaoc‘
したがって、オブジェクトのプロトタイプが IE6 7 で配列を継承する場合、長さ属性は常に 0 になると結論付けることができます。 -like オブジェクトは配列メソッドを使用する必要があるため、使用しないでください。 配列を継承する代わりに、Array.prototype.xxx.apply(obj,[]); メソッドを使用し、必ず length 属性の値を正しく初期化してください。
Object オブジェクトの長さを取得する
try{callback({ data:[{a:1},{a:2}] }); }catch(e){}
这是非常合理的,因为我在前端可以用length得到数据的长度,并逐条将其插入表格,或者是通过其他的方式表现出来。但是你永远也不能用一成不变的思维方式来解决所有问题。
某天写后台接口的同事决定换一种数据格式,改用object来表示数据,并为每个数据添加一个索引,如下所示:
try{callback({ data:{1:{a:1},2:{a:2}} }); }catch(e){}
面对这样的数据,我就犯愁了,因为object不能获取对象长度。当然我可以叫后台同事改一下接口返回的格式,但是既然他可以写出以这样格式返回的代码,那其他的后台同事也同样
可以写出。为了不影响到更多的人,就需要我在前端来做处理了。其实要获取对象的长度也不难,用for in 语句就能实现,如下代码所示:
var a = {a:1,b:2,c:3,d:4}; function length(o) { var count = 0; for(var i in o){ count ++; } return count; }; alert(length(a)); //5
至于为什么是5而不是4那是因为每个对象都有一个内部属性(proto指向原型)。
为了更方便的使用这个方法,可以把它写到Object原型里面去,如下代码所示:
var a = {a:1,b:2,c:3,d:4}; Object.prototype.length = function() { var count = 0; for(var i in this){ count ++; } return count; }; alert(a.length()); //5
这样用起来会更直观,跟接近Array的使用习惯。
以上がjqueryのlength属性の使い方を詳しく解説の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。