es6有arguments,但箭頭函數是不識別arguments的,所以用rest(剩餘參數)來取代arguments;剩餘參數直接就固定到數組裡了,而arguments是類別數組(本質是個物件) ,還需要轉換。剩餘參數語法允許將一個不定數量的參數表示為一個數組,不定參數定義方式,這種方式很方便的去聲明不知道參數情況下的一個函數。
本教學操作環境:windows7系統、ECMAScript 6版、Dell G3電腦。
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); }
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
後續傳入參數的形式和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中文網其他相關文章!