站长资讯网
最全最丰富的资讯网站

es6有没有arguments

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

es6有没有arguments

前端(vue)入门到精通课程:进入学习
Apipost = Postman + Swagger + Mock + Jmeter 超好用的API调试工具:点击使用

本教程操作环境: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));
登录后复制

赞(0)
分享到: 更多 (0)
网站地图   沪ICP备18035694号-2    沪公网安备31011702889846号