es6有沒有arguments

青灯夜游
發布: 2022-10-24 19:08:29
原創
1142 人瀏覽過

es6有arguments,但箭頭函數是不識別arguments的,所以用rest(剩餘參數)來取代arguments;剩餘參數直接就固定到數組裡了,而arguments是類別數組(本質是個物件) ,還需要轉換。剩餘參數語法允許將一個不定數量的參數表示為一個數組,不定參數定義方式,這種方式很方便的去聲明不知道參數情況下的一個函數。

es6有沒有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中文網其他相關文章!

相關標籤:
來源:php.cn
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板