es6有arguments,但箭頭函數是不識別arguments的,所以用rest(剩餘引數)來取代arguments;剩餘引數直接就固定到陣列裡了,而arguments是類陣列(本質是個物件),還需要轉換。剩餘引數語法允許將一個不定數量的參數列示為一個陣列,不定引數定義方式,這種方式很方便的去宣告不知道引數情況下的一個函數。
前端(vue)入門到精通課程:進入學習
Apipost = Postman + Swagger + Mock + Jmeter 超好用的API偵錯工具:
本教學操作環境: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 用來解決已知引數集合應用到固定引數的函數上
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");
}
登入後複製
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));
登入後複製
【相關推薦:、】
以上就是es6有沒有arguments的詳細內容,更多請關注TW511.COM其它相關文章!