es6有沒有arguments

2022-10-24 22:00:31

es6有arguments,但箭頭函數是不識別arguments的,所以用rest(剩餘引數)來取代arguments;剩餘引數直接就固定到陣列裡了,而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));
登入後複製

【相關推薦:、】

以上就是es6有沒有arguments的詳細內容,更多請關注TW511.COM其它相關文章!