简体   繁体   English

非常恼人的JavaScript数组/对象错误

[英]Extremely annoying JavaScript array/object error

Basically, I am rewriting part of one of my web applications. 基本上,我正在重写我的一个Web应用程序的一部分。 I had a script that would collapse some or all panels of the interface at once, and another to code them. 我有一个脚本可以同时折叠界面的部分或全部面板,另一个脚本可以对它们进行编码。

However, my old functions looked really ugly, and were annoying to type and not powerful enough: 但是,我的旧功能看起来很难看,而且输入很烦人而且不够强大:

function collapse_all()
{
    document.getElementById("panel_1").style.display="none"
    document.getElementById("panel_2").style.display="none"
    document.getElementById("panel_3").style.display="none"
}
function expand_all()
{
    document.getElementById("panel_1").style.display=""
    document.getElementById("panel_2").style.display=""
    document.getElementById("panel_3").style.display=""
}

Now I have this: 现在我有这个:

function panel() //first variable in argument is collapse or expand, all others are panels to act on
{
    var panels = panel.arguments
    alert(typeof panel.arguments)
    var mode = panels.shift() //here's my problem
    if(mode=="collapse") {mode="none"}
    if(mode=="expand") {mode=""}
    var items = panels.length
    for (i = 0;i < items;i++) {document.getElementById(panels[i]).style.display=mode}
}

panel("collapse","panel_1","panel_2","panel_3")

I have a problem though. 我有一个问题。 Firebug tells me panels.shift() is not a function. Firebug告诉我panels.shift()不是一个函数。 With some Googling I managed to find out that panel.arguments isn't an array but an object, so I can't use array methods on it. 通过一些谷歌搜索,我设法找出panel.arguments不是一个数组而是一个对象,所以我不能在它上面使用数组方法。 I'm just really confused as to how I could either convert the object into an array or find another workaround, as I know next to nothing about JavaScript objects. 我真的很困惑我如何将对象转换为数组或找到另一种解决方法,因为我对JavaScript对象几乎一无所知。 Some example code would be highly appreciated. 一些示例代码将受到高度赞赏。

You can convert the arguments object into an array like this: 您可以将arguments对象转换为如下数组:

var argsArray = Array.prototype.slice.call(arguments);

What this does is use the slice method common to all arrays via Array.prototype to create a genuine Array object from the array-like arguments . 这样做是通过Array.prototype使用所有数组通用的slice方法从类似数组的arguments创建一个真正的Array对象。 call() (a method of all functions) is used to call this slice method with a this value of arguments and no parameters, which has the effect of copying all of the elements of this into a new array. call()的所有功能的方法)来调用此slice与方法this的值arguments和任何参数,其具有复制所有的元素的效果this到一个新的数组。 This may seem devious or hacky but it is actually designed into the language: see the note at the bottom of section 15.4.4.10 of the ECMAScript 3rd Edition spec . 这可能看起来是狡猾或hacky,但它实际上是设计成语言:请参阅ECMAScript第3版规范第15.4.4.10节底部的注释

Also, within a function you are provided the arguments object as a variable, so you don't need to access it as a property of the function object as you are doing. 此外,在函数中,您将arguments对象作为变量提供,因此您不需要像操作那样将其作为函数对象的属性进行访问。 In your case, just use arguments rather than panel.arguments . 在您的情况下,只使用arguments而不是panel.arguments

You could keep it much simpler (cleaned up your formatting, semi-colons, etc.): 你可以保持它更简单(清理你的格式,分号等):

function panel() 
{
    var panels = Array.prototype.slice.call(arguments);
    var displayMode = (panels[0] == "collapse" ? "none" : "");

    for (var i = 1; i < panels.length - 1; i++) 
    {
        document.getElementById(panels[i]).style.display = displayMode;
    }
}

Also, if you're rewriting your application, it might be a good time to consider using things like jQuery . 此外,如果您正在重写您的应用程序,那么可能是考虑使用jQuery之类的东西的好时机。 You could assign each one of your panels a certain class name, and reduce your code to something like this: 您可以为每个面板指定一个特定的类名,并将代码缩减为:

function panel(hide)
{
    $('.className').css({ display: (hide ? 'none' : '') });
}

which you could use like so: 您可以这样使用:

panel(true); // or
panel(false);

Or , because now it's so syntactically simple, you might as well just create two separate functions so that your code is straightforward and you know exactly what it's going to do from the function names alone: 或者 ,因为现在它在语法上很简单,所以你可以创建两个独立的函数,这样你的代码就很简单了,而且你只知道它将从函数名称中做到的确切:

function showPanels() {
    $('.className').css({ display: '' });
}

function hidePanels() {
    $('.className').css({ display: 'none' });
}

And finally, if you don't worry about doing it via CSS, you could really shorten your script to this, which can't be any clearer: 最后,如果你不担心通过CSS来做,你可以真正缩短你的脚本,这不能更清楚:

function showPanels() {
    $('.className').show();
}

function hidePanels() {
    $('.className').hide();
}

Cheers! 干杯!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM