JavaScript中的哪些对象具有.length属性?(也就是为什么下划线u.each将我的函数对象视为数组?)
我一直认为只有JavaScript中的哪些对象具有.length属性?(也就是为什么下划线u.each将我的函数对象视为数组?),javascript,underscore.js,Javascript,Underscore.js,我一直认为只有Array对象才具有.length属性。但是,再一次,我也看到了提到的“类似阵列”的对象。我还没有研究过这个问题,现在看来我对JS中这个主题的无知可能会让我头疼。举个例子: 我有以下代码: var View = function(options) { // code }; _.extend(View, Backbone.Events, { make_children: function(parent) { // code } }); 稍后,我
Array
对象才具有.length
属性。但是,再一次,我也看到了提到的“类似阵列”的对象。我还没有研究过这个问题,现在看来我对JS中这个主题的无知可能会让我头疼。举个例子:
我有以下代码:
var View = function(options) {
// code
};
_.extend(View, Backbone.Events, {
make_children: function(parent) {
// code
}
});
稍后,我将此视图
函数
与下划线一起使用。每个决定此函数对象是一个数组,因为它有一个.length
属性:
// Code from Underscore.js's `_.each`:
} else if (obj.length === +obj.length) { // This is true
for (var i = 0, l = obj.length; i < l; i++) { // **So, execution goes here**
if (iterator.call(context, obj[i], i, obj) === breaker) return
}
} else {
for (var key in obj) {
if (_.has(obj, key)) { // **Execution does __not__ go here**
if (iterator.call(context, obj[key], key, obj) === breaker) return;
}
}
}
JavaScript中的哪些对象具有.length
属性
根据oh-so重言式的定义,任何具有长度
属性的对象
length
是函数对象的一个属性,指示函数需要多少参数,即形式参数的数量
这也是类似于数组的,因为它具有长度
:
var foo = {
bar: true,
baz: 'quux',
length: 42
}
这里的问题是
underline.js
,与jquery
非常相似,它们都在各自的函数中使用.length
属性作为标志。当length
属性存在时,该函数假定传递的参数可以使用普通for循环进行迭代。此逻辑背后的原因是,当定义length
属性时,可以按顺序迭代参数,这就是使用for循环的原因
误用length
的结果本质上是一种名称冲突,其中存在意外结果。我建议将length
改为另一个同义词,如size
或capacity
或totalViews
等
编辑
如果没有其他选择供您使用,并且您必须在保留的同时保留长度。每个的功能,那么您可以稍微修改一下。此插件适用于下划线版本1.4.3的缩小版本
var s = Array.prototype.ForEach;
var r = {};
var myEach = function (n,t,e){if(null!=n)if(s&&n.forEach===s)n.forEach(t,e);else if(n.length===+n.length&&typeof(n[0])!="undefined"){for(var u=0,i=n.length;i>u;u++)if(t.call(e,n[u],u,n)===r)return}else for(var a in n)if(_.has(n,a)&&t.call(e,n[a],a,n)===r)return};
_.each=myEach;
下面是一个演示:
基本上,当length
属性存在但typeof(yourObject[0])==“undefined”
时,它使用forEach
。烦人的遗憾的是,谷歌无法找到这一点。一定是我的错。谢谢。那么,你有没有关于我该如何做的建议?我应该做什么。。。使用我自己的\每个类型的函数?我认为它说得很好:“除非另有规定,否则该值等于最大数量的命名参数…包括可选参数”同意@RobG对您的操作的评论。我不确定您的问题是否与函数
有长度
属性有关。所有函数都至少有一个长度属性,字符串也是如此。@magritte:+++1用于将我指向dochub.io。以前从未使用过。obj[1]
将永远不会被调用,因为如果长度为1,i为1,那么1为什么要将函数对象传递给需要数组(或类似数组的对象)的函数?很有趣。你的意思是:首先我将函数对象的.length
复制到更合适的命名属性,然后我应该去掉它,或者对它做一些事情,使它不能通过测试。。。我昨天刚刚看了这个演示:内置操作:@dimadima per,除了更改函数声明中形式参数的数量外,不能修改函数的length属性。您也不能删除它:此子句中描述的内置函数对象的length属性具有属性{[[Writable]]:false、[[Enumerable]]:false、[[Configurable]]:false}
@dimadima-如果这是框架的工件,那么这是他们做出的一个不幸选择。我不确定框架中还有哪些地方使用了它,因此其他地方可能需要它。我注意到,您提取了一些源代码,这是一个很好的方法,可以触及您所面临问题的核心。如果您确实删除了length属性(例如,您没有显式添加它,而框架不明智地选择添加它),那么请确保您没有破坏其他功能。@RobG:是的,刚刚通过反复试验发现了这一点。感谢您确认:D@TravisJ:正如@RobG所指出的,看起来我被这个函数的.length
所困扰。我得想个办法。无论如何,这都是测试/规范的全部内容。最坏的情况。。。我将写出我的每个测试用例。
var s = Array.prototype.ForEach;
var r = {};
var myEach = function (n,t,e){if(null!=n)if(s&&n.forEach===s)n.forEach(t,e);else if(n.length===+n.length&&typeof(n[0])!="undefined"){for(var u=0,i=n.length;i>u;u++)if(t.call(e,n[u],u,n)===r)return}else for(var a in n)if(_.has(n,a)&&t.call(e,n[a],a,n)===r)return};
_.each=myEach;