Does es6 have arguments?

青灯夜游
Release: 2022-10-24 19:08:29
Original
1101 people have browsed it

es6 has arguments, but the arrow function does not recognize arguments, so rest (remaining parameters) are used to replace arguments; the remaining parameters are directly fixed to the array, and arguments are array-like (essentially an object) , still needs to be converted. The remaining parameter syntax allows an indefinite number of parameters to be expressed as an array, and the parameter definition method is variable. This method is very convenient to declare a function without knowing the parameters.

Does es6 have arguments?

The operating environment of this tutorial: Windows 7 system, ECMAScript version 6, Dell G3 computer.

1. Usage of arguments

1. Description

arrow function in es6 Arguments are not recognized. So use rest instead of arguments.

After ES6, arguments are replaced by remaining parameters. The remaining parameters are directly fixed into the array, while arguments are array-like (essentially an object) and need to be converted.

2. Common operations on arguments

(1). Get the parameter length

(2). Get the parameters according to the index

(3). Get the function where the current arguments are located

Code sharing:

{
  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);
}
Copy after login

3. Convert arguments into an array

{
  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);
}
Copy after login

4. There are no arguments in arrow functions

{
  console.log("----------------3. 箭头函数中没有arguments-------------------");
  let Test3 = () => {
    console.log(arguments);
  };
  Test3(1, 2, 3, 4);
}
Copy after login

2. ES6 rest parameters and expansion operators

1. Rest Parameter

The remaining parameter syntax allows us to express an indefinite number of parameters as an array and an indefinite parameter definition method. This method is very convenient to declare a function without knowing the parameters.

Code Sharing

{
  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]
}
Copy after login

2. Spread Operator

"Break up" the fixed array contents into corresponding parameters.

Code sharing:

{
  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);
}
Copy after login

Summary:

1. Spread Operator and Rest Parameter are operators with similar appearance but opposite meanings. Simply put, Rest Parameter "converges" the variable parameters into arrays, while Spread Operator "breaks up" the fixed array contents into corresponding ones. parameter.

2. Rest Parameter is used to solve the scenario where function parameters are uncertain, and Spread Operator is used to solve the problem of applying a known parameter set to a function with fixed parameters

3. Summary of apply/call/bind usage

1. Both apply and call are used to change the pointer of this in the called function , and execute the function immediately

2. Bind is also used to change the pointer of this in the function, but it returns a function that needs to be called before it can be executed

3. The first parameter of apply and call is passed in and bound to the object, which is used to change the point of this, but

(1). apply is to put the parameters that need to be passed into the function into an array, and pass it in to the position of the second parameter

(2). Call is to pass in the required parameters in sequence from the 2nd, 3rd, 4th.... positions

4. bind The format of subsequent incoming parameters is the same as call, and the required parameters are passed in sequentially from the 2nd, 3rd, 4th.... , bind returns a function and needs to be called again.

Code sharing:

// 案例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");
}
Copy after login

4. Apply/call/bind is implemented with js

1. apply

(1). xxFn.ypfapply(), in ypfapply, this points to the xxFn function

(2). When it is necessary to enter and exit null or undefined, this points to 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);
Copy after login

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);
Copy after login

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));
Copy after login

【相关推荐:javascript视频教程编程视频

The above is the detailed content of Does es6 have arguments?. For more information, please follow other related articles on the PHP Chinese website!

Related labels:
source:php.cn
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template
About us Disclaimer Sitemap
php.cn:Public welfare online PHP training,Help PHP learners grow quickly!