• 技术文章 >web前端 >前端问答

    es6有没有arguments

    青灯夜游青灯夜游2022-10-24 19:08:29原创175

    es6有arguments,但箭头函数是不识别arguments的,所以用rest(剩余参数)来取代arguments;剩余参数直接就固定到数组里了,而arguments是类数组(本质是个对象),还需要转换。剩余参数语法允许将一个不定数量的参数表示为一个数组,不定参数定义方式,这种方式很方便的去声明不知道参数情况下的一个函数。

    大前端成长进阶课程:进入学习

    本教程操作环境:windows7系统、ECMAScript 6版、Dell G3电脑。

    一、arguments用法

    1. 说明

    es6中箭头函数是不识别arguments的。所以用rest来取代arguments。

    ES6之后,都用剩余参数代替arguments了,剩余参数直接就固定到数组里了,而arguments是类数组(本质是个对象),还需要转换。

    2. arguments的常用操作

    (1). 获取参数长度

    (2). 根据索引获取参数

    (3). 获取当前arguments所在的函数

    代码分享:

    {
      console.log("----------------1. arguments常用操作-------------------");
      function Test1() {
        // arguments长什么样?---本质是一个对象
        // {
        //     '0': 1,
        //     '1': 2,
        //     '2': 3,
        //     '3': 4,
        //     '4': 5,
        //     '5': 6,
        //     '6': 7,
        //     '7': 8
        //   }
        console.log(arguments);
    
        // 常见的对arguments的操作是三个
        // 1.获取参数的长度
        console.log(arguments.length);
    
        // 2.根据索引值获取某一个参数
        console.log(arguments[0]);
        console.log(arguments[1]);
        console.log(arguments[2]);
    
        // 3.callee获取当前arguments所在的函数
        console.log(arguments.callee);
      }
    
      //调用
      Test1(1, 2, 3, 4, 5, 6, 7, 8);
    }

    3. 将arguments转换成数组

    {
      console.log("----------------2. 将arguments转换成数组-------------------");
      function Test2() {
        // 方案1-自己遍历
        {
          let newArray = [];
          for (let i = 0; i < arguments.length; i++) {
            newArray.push(arguments[i]);
          }
          console.log(newArray);
        }
        // 方案2-Array.prototype.slice将arguments转成array
        {
          let newArray2 = Array.prototype.slice.call(arguments);
          console.log(newArray2);
        }
        // 方案3-ES6语法 Array.From
        {
          console.log(Array.from(arguments));
        }
        // 方案4-ES6语法 剩余参数
        {
          console.log([...arguments]);
        }
      }
    
      //调用
      Test2(1, 2, 3, 4, 5, 6, 7, 8);
    }

    4. 箭头函数中没有arguments

    {
      console.log("----------------3. 箭头函数中没有arguments-------------------");
      let Test3 = () => {
        console.log(arguments);
      };
      Test3(1, 2, 3, 4);
    }

    二. ES6剩余参数和展开运算符

    1. 剩余参数(Rest Parameter)

     剩余参数语法允许我们将一个不定数量的参数表示为一个数组,不定参数定义方式,这种方式很方便的去声明不知道参数情况下的一个函数。

    代码分享

    {
      console.log("-----------------1. 剩余参数---------------------");
      function sum1(...nums) {
        console.log(nums);
        console.log(
          nums.reduce((preValue, currentValue) => preValue + currentValue, 0)
        ); //求和
      }
      //调用
      sum1(1, 2); //[1,2]
      sum1(1, 2, 3); //[1,2,3]
      sum1(1, 2, 3, 4); //[1,2,3,4]
    
      function sum2(num1, num2, ...nums) {
        console.log(nums);
        console.log(
          nums.reduce(
            (preValue, currentValue) => preValue + currentValue,
            num1 + num2
          )
        ); //求和
      }
      //调用
      sum2(1, 2); //[]
      sum2(1, 2, 3); //[3]
      sum2(1, 2, 3, 4); //[3,4]
    }

    2. 展开运算符(Spread Operator)

     把固定的数组内容“打散”到对应的参数。

    代码分享:

    {
      console.log("-----------------2. 展开运算符---------------------");
      function sum1(num1, num2) {
        console.log(num1 + num2);
      }
      // 调用
      let arry1 = [10, 20];
      sum1(...arry1);
    
      function sum2(num1, num2, num3) {
        console.log(num1 + num2 + num3);
      }
      //调用
      let arry2 = [10, 20, 30];
      sum2(...arry2);
    }

    总结:

    1. Spread Operator 和 Rest Parameter 是形似但相反意义的操作符,简单的来说 Rest Parameter 是把不定的参数“收敛”到数组,而 Spread Operator 是把固定的数组内容“打散”到对应的参数。

    2. Rest Parameter 用来解决函数参数不确定的场景,Spread Operator 用来解决已知参数集合应用到固定参数的函数上

    三. apply/call/bind用法总结

    1. apply 和 call都是为了改变被调用函数中this的指向, 同时立即执行该函数

    2. bind也是为了改变函数中this的指向,但它返回的是一个函数,需要被调用才能执行

    3. apply 和 call的第一个参数都是传入绑定到对象,用于改变this指向,但是

    (1). apply是将需要传入函数的参数放到一个数组里,传入到第二个参数的位置

    (2). call是从第2,3,4.....位置依次传入需要的参数

    4. bind 后续传入参数的形式和call相同,从第2,3,4.....位置依次传入需要的参数,bind返回的是一个函数,需要再次调用

    代码分享:

    // 案例1--隐式绑定
    {
      console.log("----------------案例1--------------------");
      let name = "ypf1";
      let age = 18;
      let obj = {
        name: "ypf2",
        myAge: this.age,
        getMsg: function () {
          console.log(this.name, this.age);
        },
      };
      // 调用
      console.log(obj.myAge); //undefined (隐式绑定,this指向obj)
      obj.getMsg(); //ypf2,undefined  (隐式绑定,this指向obj)
    }
    
    //案例2--只绑定,不传参
    /* 
        注意1个细节,bind后面多了个(),bind返回的是一个新函数,必须调用才能执行
    */
    {
      console.log("----------------案例2--------------------");
      let name = "ypf1";
      let age = 18;
      let obj = {
        name: "ypf2",
        myAge: this.age,
        getMsg: function () {
          console.log(this.name, this.age);
        },
      };
      let obj2 = { name: "ypf3", age: 35 };
      // 调用
      obj.getMsg.apply(obj2); //ypf 35 (apply显式绑定优先级高于隐式绑定,this指向obj2)
      obj.getMsg.call(obj2); //ypf 35 (call显式绑定优先级高于隐式绑定,this指向obj2)
      obj.getMsg.bind(obj2)(); //ypf 35 (bind显式绑定优先级高于隐式绑定,this指向obj2)
    }
    
    // 案例3--传递参数
    /* 
        apply传递数组
        call和bind都是依次写参数
        特别注意:bind可以多次传递参数
    */
    {
      console.log("----------------案例3--------------------");
      let name = "ypf1";
      let age = 18;
      let obj = {
        name: "ypf2",
        myAge: this.age,
        getMsg: function (msg1, msg2) {
          console.log(this.name, this.age, msg1, msg2);
        },
      };
      let obj2 = { name: "ypf3", age: 35 };
      //调用
      obj.getMsg.apply(obj2, ["消息1", "消息2"]);
      obj.getMsg.call(obj2, "消息1", "消息2");
      //bind用法1
      obj.getMsg.bind(obj2, "消息1", "消息2")();
      //bind用法2--多次传参
      let fn1 = obj.getMsg.bind(obj2, "消息1");
      fn1("消息2");
    }

    四. apply/call/bind用js实现

    1. apply

    (1). xxFn.ypfapply(), 在ypfapply中,this指向xxFn函数

    (2). 需要实现出入 null 或 undefined的时候,this指向window

    (3). 使用 delete 可以删除对象的某个属性

    (4). 通过Function.prototype原型添加

    (5). || 用法

    argArray = argArray?argArray:[] 等价于

    argArray = argArray || []

    代码分享:

    /**
     * 利用js手写call函数
     * @param {Object|null|undefined} thisArg 待绑定的对象
     * @param  {Array} argArray 调用函数的数组参数
     */
    Function.prototype.ypfapply = function (thisArg, argArray) {
      // 1. this指向调用函数
      let fn = this;
    
      // 2. 获取传递参数
      thisArg = thisArg != null && thisArg != undefined ? Object(thisArg) : window;
    
      //3. 赋值函数并调用
      thisArg.fn1 = fn;
      argArray = argArray || [];
      let result = thisArg.fn1(...argArray);
    
      //4. 删除thisArg绑定的属性
      delete thisArg.fn1;
    
      //5.返回结果
      return result;
    };
    
    // 测试
    function test1() {
      console.log(this);
    }
    function sum(num1, num2) {
      console.log(this, num1, num2);
      return num1 + num2;
    }
    
    // 1. 利用系统自带的apply测试
    console.log("----------1.利用系统自带的call测试---------------");
    test1.apply(null);
    let result1 = sum.apply("ypf1", [10, 20]);
    console.log(result1);
    
    // 2. 利用自己写的测试
    console.log("----------2.利用自己写的测试---------------");
    test1.ypfapply(null);
    let result2 = sum.ypfapply("ypf1", [10, 20]);
    console.log(result2);

    2. call

    (1). xxFn.ypfcall(), 在ypfcall中,this指向xxFn函数

    (2). 需要实现出入 null 或 undefined的时候,this指向window

    (3). 使用 delete 可以删除对象的某个属性

    (4). 通过Function.prototype原型添加

    代码分享:

    /**
     * 利用js手写call函数
     * @param {Object|null|undefined} thisArg 待绑定的对象
     * @param  {...any} args 调用函数的参数
     */
    Function.prototype.ypfcall = function (thisArg, ...args) {
      // 1. 指向待调用的函数
      let fn = this;
    
      //2. 获取绑定对象
      thisArg = thisArg != null && thisArg != undefined ? Object(thisArg) : window;
    
      //3.调用函数
      thisArg.fn1 = fn;
      let result = thisArg.fn1(...args);
    
      //4. 删除多余的属性
      delete thisArg.fn1;
    
      //5. 最终返回
      return result;
    };
    
    // 测试
    function test1() {
      console.log(this);
    }
    function sum(num1, num2) {
      console.log(this, num1, num2);
      return num1 + num2;
    }
    
    // 1. 利用系统自带的call测试
    console.log("----------1.利用系统自带的call测试---------------");
    test1.call(undefined);
    let result1 = sum.call("ypf1", 10, 20);
    console.log(result1);
    
    // 2. 利用自己写的测试
    console.log("----------2.利用自己写的测试---------------");
    test1.ypfcall(undefined);
    let result2 = sum.ypfcall("ypf1", 10, 20);
    console.log(result2);

    3. bind

    (1). bind和call相同,接收到参数是依次传递,另外bind返回的是函数!!

    (2). xxFn.ypfbind(), 在ypfbind中,this指向xxFn函数

    (3). 需要实现出入 null 或 undefined的时候,this指向window

    (4). 使用 delete 可以删除对象的某个属性

    (5). 由于bind返回的是函数,所以需要声明1个函数, 并返回这个函数

    函数内部核心点:由于bind可以一次性传递参数,也可以多次传递参数,所以需要对两个参数进行一下合并

    代码分享:

    Function.prototype.ypfbind = function (thisArg, ...argArray) {
      // 1. this指向调用的函数
      let fn = this;
    
      // 2. 处理绑定参数
      thisArg = thisArg != null && thisArg != undefined ? Object(thisArg) : window;
    
      // 3. 声明一个函数
      function DyFun(...argArray2) {
        // 绑定函数
        thisArg.fn1 = fn;
        // 合并参数
        let finalArgArray = [...argArray, ...argArray2];
        // 调用函数
        let result = thisArg.fn1(...finalArgArray);
        // 删除用完的属性
        delete thisArg.fn1;
        // 返回结果
        return result;
      }
    
      //4. 返回一个函数
      return DyFun;
    };
    
    // 测试
    function test1() {
      console.log(this);
    }
    function sum(num1, num2) {
      console.log(this, num1, num2);
      return num1 + num2;
    }
    // 1. 利用系统自带的bind测试
    console.log("----------1. 利用系统自带的bind测试---------------");
    test1.bind(undefined)();
    let result1 = sum.bind("ypf1", 10, 20);
    console.log(result1());
    let result2 = sum.bind("ypf2", 10);
    console.log(result2(30));
    
    // 2. 利用自己写的测试
    console.log("----------2.利用自己写的测试---------------");
    test1.bind(undefined)();
    let result3 = sum.bind("ypf1", 10, 20);
    console.log(result3());
    let result4 = sum.bind("ypf2", 10);
    console.log(result4(30));

    【相关推荐:javascript视频教程编程视频

    以上就是es6有没有arguments的详细内容,更多请关注php中文网其它相关文章!

    声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn核实处理。

    前端(VUE)零基础到就业课程:点击学习

    清晰的学习路线+老师随时辅导答疑

    自己动手写 PHP MVC 框架:点击学习

    快速了解MVC架构、了解框架底层运行原理

    专题推荐:javascript ES6
    上一篇:es6解构支持字符串吗 下一篇:自己动手写 PHP MVC 框架(40节精讲/巨细/新人进阶必看)

    相关文章推荐

    • ❤️‍🔥共22门课程,总价3725元,会员免费学• ❤️‍🔥接口自动化测试不想写代码?• javascript怎么正则替换非汉字的字符• javascript怎么求数组中的最大奇数• JavaScript怎么输入N个数据求平均数• 一文详解JavaScript中执行上下文与执行栈(图文结合)• 一文详解 JavaScript 中展开运算符的不同使用方式
    1/1

    PHP中文网