解释都在代码里..<script type="text/javascript">
var join = function () {
    for (var i = 0, b = ''; i < this.length ; i ++) {
        if (i) b+= arguments[0];
        b += this[i];
    }
    return b;
};var show = function () {
    //new Array(arguments)).join('_');
    //try
    try {
        alert(
            Array.apply(null, arguments).join('_')
        );
        return join.call(arguments, '-'); //Array.prototype.join就类似于window.join方法.apply,call不会改变scope,可参考finally里的内容
    } finally {
        var func = function () {
            alert(a);
        };
        
        void function () {
            var a = 1;
            try {
                func.call(this);
            } catch (exp) {
                alert(exp.message);
            }
        }();
    }
};alert(show(1, 2, 3, 5));

解决方案 »

  1.   

    ??
    上述代码放到一个空的html里什么结果也没有产生?
    楼上的在发表代码之前是否验证过呢?而且,打几个文字就这么困难?也不愿意说明一下。
    我看MSDN上很多MS的senior的developer回答问题也并非贴段代码就了事的。
      

  2.   

    少粘了个script结束标记.
    我认为这种问题,用代码来解决最明白了.
    apply的原理你已经知道了,所以没有什么好解释的了.
    并且我代码里有关键注释.
      

  3.   

    呵呵,其实少粘了格结束标记我也看到了。只是提醒你一下不要太急躁。现在太多人就是太急躁了。另外,你的代码里finally里面的内容完全没有必要,我并不是在问scope的问题。而且,你的代码如果我没理解错,是实现了一下join函数,然后用Array.apply把arguments变成Array对象去调用Array的join方法,
    return join.call(arguments, '-');这句是调用你自己写的join方法变量,也就是window.join方法但这并没有回答我的问题,我不是不知道定义函数变量后调用call方法。
    我再强调一下原文的问题:
    。那么问题出现了,这个转化又是怎么发生的呢?是系统调用了Array的构造函数吗?
    这是确认call和apply的具体实现中是不是调用了构造函数来构造Array对象。
    然后下面还有一个问题:
    (new Array(arguments)).join('_') 为什么会报错?
    new Array(arguments)这部分是可以得到一个Array对象的,但为什么它不能调用join方法呢?
      

  4.   

    哈,我发现第二个问题的答案了。new Array(arguments)虽然是可以得到一个Array对象,但是Array的构造函数把参数一个个地分配到
    数组的元素中,所以实际上这个得到的Array永远只有一个元素,就是arguments。
    即使arguments里有1,2,3,5四个参数,得到的Array也只有一个元素,length=1。这个Array调用join方法,得到的是"[object Object]",
    倒是不会报错。而是该arguments对象的toString()得到的结果。但是我的问题仍然没有解决: new Array(arguments)不能“正确”(实际上是按我想的把参数逐一地放到数组里)地得到Array,那么
    Array.prototype.join.call(arguments, '_');又是怎么去转化的呢?按muxrwc的代码里Array.Apply(null,arguments)可以把arguments转化成Array对象(而且是逐一地放置元素),是不是调用了它呢?
    有什么证据呢?
      

  5.   

    <script type="text/javascript">
    /*

    最近天天困困的而且是从文件中粘贴出那段调试代码。忘记粘那段script了。
    既然知道函数后.call
    可以调用函数改变this的引用
    那么下面这个直接用Array构造创建object对象和.call是一样的道理
    */
    alert(Array(1, 2, 3));(function () {
    alert(Array(arguments)[0] === arguments); //即[arguments]
    alert((new Array(arguments))[0] === arguments); //即[arguments]
    //上面两个是等同的
    //这个和Function类是一样的.
    //你1楼已经说的很清楚了
    alert((new Array(arguments)).join('_'));
    //这个你也说了[arguments].join自然就是arguments.toString所以是[object...]
    //你那里说报错??怎么可能?你不是直接拿着你上面的那个双字节的小左括号测试的吧。。
    }(1, 2, 3));
    </script>
      

  6.   

    call
    apply第一个参数
    是this的引用地址call函数的2-n参数是
    向调用函数传递的1到n-1个参数.而
    apply
    第二个参数是
    一个数组或者arguments对象
    把这个组展开放到调用函数的形参中.(展开,是下标相对应的放)
      

  7.   

    报错那个我现在也重现不出来,只是当时在VS的debug模式下报对象不支持该方法之类的错。
    你上面两楼的答案和我上一楼的基本一样。对new方法调用Array的constructor不能构造“展开”的数组已经没有疑问。我的问题现在就是纯粹的对JS这样的弱类型语言里类型转化的实现的一个疑问。
    function ClassA()
    {
    this.p1="pa";
    }ClassA.getP1=function()
    {

    return this.p1;}
    function ClassB()
    {

    ClassA.apply(this,arguments);
    this.p1="pb";
    }b=new ClassB();
    alert( ClassA.getP1.apply(b) );结果还是pb,表面上看很明显,b是ClassB的对象,它的p1当然是pb而不是pa。
    但这说明了JS内部有一种机制,不经过构造函数而实现不同类型对象的转化。
    可能是受c++的copy constructor的影响,总觉得怎么可能不经过构造函数就可以进行类型转换呢?而且JS严格来说并没有定义ClassA和ClassB的关系。
    也就不会有VirtualTable之类的东西。要进行late-binding就比较神奇了啊
      

  8.   

    似乎全靠这个this指针来寻找属性,比如this.p1
    所以对Array来说,join方法只需要[]操作符就可以进行,所以可以直接接受arguments对象,即使他不是Array对象,但
    他含有[]方法和length属性。如果this是通过方法/属性名就可以寻找到内存中合适的数据。那么确实不需要做类型转换。
    直接call/apply就行了。随便乱写,结贴了
      

  9.   

    呵...
    new 方法其实是调用Object的构造来实例化array的.
    所以typeof 实例化后的array对象,才是object
    只不过,最底层的prototype chain是array.prototype chain...偶是这么理解的...
    具体的解释方式也不是那么清楚...