zoukankan      html  css  js  c++  java
  • 永远不要修改arguments对象

    案例复现

    var obj = {
       plus: function(arg0, arg1) { return arg0 + arg1; }
    };
    
    function callMethod(context, method, arg0, arg1) {
       var shift = [].shift;
       shift.call(arguments);
       shift.call(arguments);       
    
       // Cannot call method 'apply' of undefined
       return context[method].apply(context, arguments);        
    }
    var result = callMethod(obj, 'plus', 17, 2);
    

    该函数出错的原因是arguments对象并不是函数参数的副本。要注意的是,所有命名参数都是arguments对象中对应索引的别名。因此,即使通过shift方法移除arguments对象中的元素之后,context仍然是arguments[0]的别名,method仍然是arguments[1]的别名。这意味着,我们想提取的是context['plus'],但结果是17[2]。此时一切开始失控了!

    代码注释版

    function callMethod(context, method, arg0, arg1) {
        var shift = [].shift;
        shift.call(arguments);
        shift.call(arguments);      // 此时的arguments: [1, 2]
        // context是arguments[0]的别名,值为1
        // 同理method的值为2
    
        // Cannot call method 'apply' of undefined
        return context[method].apply(context, arguments);       
    }
    

    解决方案

    我们可以通过复制arguments对象修复callMethod函数的实现。

    // 解决方案
    function callMethod(context, method, arg0, arg1) {
        var args = [].slice.call(arguments, 2);
        return context[method].apply(context, args);
    }
    

    总结

    • 永远不要修改arguments对象
    • 使用[].slice.call(arguments)将arguments对象复制到一个真正的数组中再进行修改

    参考:编写高质量JavaScript代码的68个有效方法

  • 相关阅读:
    RxJava系列7(最佳实践)
    异步编程 z
    利用WCF的双工通讯实现一个简单的心跳监控系统 z
    c#深拷贝
    MEF load plugin from directory
    C# 文件操作 把文件读取到字节数组
    code md5
    gridview转成EXCEL文件保存(多页)
    Getting started with SciPy for .NET
    IronPython调用C# DLL函数方法
  • 原文地址:https://www.cnblogs.com/mackxu/p/arguments.html
Copyright © 2011-2022 走看看