ES6中的函数(函数参数、默认值、箭头函数)

一、函数参数的解构赋值

function foo([a,b]) {
      console.log(a+b); // 3
}
foo([1,2]);

function bar({c,d}) {
      console.log(c+d); // 7
}
bar({c:3,d:4});

二、函数默认参数

2.1 基本方式

function foo(a,b=10) {
      console.log(a+b); // 1+10=11 => 11
}
foo(1);

function bar([a,b=10]) {
      console.log(a+b); // 3+10=13 => 13
}
bar([3]);

function fn({a,b=10}) {
      console.log(a+b); // 5+10=15 => 15
}
fn({a:5});

2.2 可以预设实参

function bar([a,b=10] = [20]) {
      console.log(a+b); // 20+10=20 => 20
}
bar();

function fn({a,b=10} = {a:20}) {
      console.log(a+b); // 20+10=30 => 30
}
fn();

2.3 预设实参的覆盖

但如果传入实参,那么就会把预设的覆盖。

function bar([a,b=10] = [20]) {
      console.log(a+b);
}
bar([100]); // 100+10 => 110
bar([100, 200]); // 100+200 => 300

function fn({a,b=10} = {a:20}) {
      console.log(a+b);
}
fn({a:100}); // 100+10 => 110
fn({a:100,b:200}); // 100+200 => 300

2.4 默认值可以是函数

function getB() {return 10};
function foo(a,b=getB()) {
      console.log(a+b); // 1+10=11 => 11
}
foo(1);

三、箭头函数

语法:参数=>函数体

  • 单行语句可以省略花括号,如果还是return语句,还可以省略return关键字。
  • 多行语句不可以省略花括号。
  • 一个参数可以省略圆括号,多个参数不可以省略圆括号。
// 传统写法(无参数)
let fn = function() {return 1;}
// 箭头函数写法
let fn = ()=>(1);
let fn = ()=>1;

// 传统写法(一个参数)
let bar = function(a) {return 2};
// 箭头函数写法
let bar = (a)=>2;
let bar = a=>2;

// 传统写法(多个参数)
let fn = function(a,b) {return a+b};
// 箭头函数写法
let fn = (a,b)=>a+b;

// 多行语句时不可省略花括号
let br = function(a,b) {
      let res = a+b;
      return res;
}
let br = (a,b)=>{
      let res = a+b;
      return res;
}

四、箭头函数的特点

4.1 箭头函数内的this固定化

函数体内的this对象是固定的,就是定义时所在的对象,而不是使用时所在的对象。

  • 普通函数内的this情境
var id = 10;
let obj = {
      id: 15,
      fn: function(){
            setTimeout(function(){
                  alert(this.id); // 10
             },1000)
      }
}
obj.fn();

分析:1秒后执行window.setTimeout(),this指向window,因此返回的结果是全局下的id:10

如果想要获取obj内的id,一般采用_this = this的办法。

var id = 10;
let obj = {
      id: 15,
      fn: function(){
            _this = this; // 调用后,这里的this指向obj
            setTimeout(function(){
                  alert(_this.id); // 15
             },1000)
      }
}
obj.fn();
  • 箭头函数内的this情境(1)
var id = 10;
let obj = {
      id: 15,
      fn: function(){
            setTimeout(()=>{
                  alert(this.id);
             },1000)
      }
}
obj.fn(); // 15
obj.fn.call({id:123}); // 123

分析:setTimeout()中用了箭头函数,因此箭头函数内的this对象就固定在父级作用域下的this上。(这里就是函数fn)
也就是说,fn函数内的this指向了谁,箭头函数的this就指向了谁。
当被obj调用时,fn函数的this指向了obj,所以返回obj下的id:15
当被对象{id:123}调用时,fn函数的this指向了{id:123},所以返回该对象下的id:123

  • 箭头函数内的this情境(2)
var id = 10;
let obj = {
      id: 15,
      fn: ()=>{
            setTimeout(()=>{
                  alert(this.id);
             },1000)
      }
}
obj.fn(); // 10
obj.fn.call({id:123}); // 10

分析:当obj下的fn方法也用箭头函数,那么就会沿着作用域链往上找它的父级作用域的this,这里找到的是全局window。
于是this就固定在了window上,不管谁去调用它,它都只会返回window下的id:10

4.2 箭头函数没有arguments对象

普通函数在初始化的过程中,会产生一个arguments对象用来保存实参。
但是在箭头函数中是不存在的,如果要使用实参列表,那么用rest参数来代替。

// 普通函数
let fn = function(a,b,c) {
      console.log(arguments);
}
fn(1,2,3);

// 箭头函数
let bn = (...args)=> {
      console.log(args);
}
bn(1,2,3);

4.3 箭头函数不可以用new实例化

let Person = (name)=> {
      this.name = name;
}
let p = new Person('mm'); // TypeError: Person is not a constructor

4.4 箭头函数不可以使用yield命令

五、箭头函数的使用场景

  • 当我们要维护一个this上下文环境时,就可以用箭头函数。
var id = 10;
let obj = {
      id: 15,
      fn: function(){
            setTimeout(()=>{
                  alert(this.id);
             },1000)
      }
}
obj.fn(); // 15
  • 定义对象方法,且要用到this时,不要用箭头函数!
let person = {
      name: 'mm',
      say: ()=>{
            console.log(this.name); // 'gg'
      }
}
var name = 'gg';
person.say();
  • 监听DOM事件时,不要用箭头函数!
let box = document.getElementById('box');
box.addEventListener('click', function(){
      if(this.classList!='red') {
            this.classList = 'red';
      }else {
            this.classList = 'green';
      }
      console.log(this); // box
});

box.addEventListener('click', ()=>{
      if(this.classList!='red') {
            this.classList = 'red';
      }else {
            this.classList = 'green';
      }
      console.log(this); // window
});

六、总结

  1. 函数参数也可以解构赋值。
  2. 函数参数可以设置默认值,可以预设实参。
  3. 函数参数的默认值可以是函数调用。
  4. 箭头函数的语法:参数=>函数体
  5. 箭头函数的this是固定的,指向了父级作用域的this。
  6. 箭头函数没有arguments,可以用rest参数代替。
  7. 箭头函数不可以new实例化。
  8. 箭头函数不可以使用yield命令
(0)

相关推荐

  • 函数之间可以相互调用

    函数之间是可以相互调用的,把一个函数作为参数传递给另一个函数. function fn1() { console.log(111); fn2(); console.log('fn1'); } func ...

  • JavaScript this 关键字详解

    一.前言 this关键字是JavaScript中最复杂的机制之一.它是一个很特别的关键字,被自动定义在所有函数的作用域中.对于那些没有投入时间学习this机制的JavaScript开发者来说,this ...

  • 前端面试题之JavaScript

    ES6语法有哪些,分别怎么用 参考链接:http://es6.ruanyifeng.com/ new的执行过程 创建一个空对象: 将构造函数的 prototype 属性赋值给新对象的 __proto_ ...

  • js中this的指向-笔记

    普通函数:this 永远指向调用它的对象,new的时候,指向new出来的对象. 箭头函数:箭头函数没有自己的 this,当在内部使用了 this时,它会指向最近一层作用域内的 this. //例1 v ...

  • JS的绑定对象this

    this的含义 this表示的是绑定的对象,通常在函数中使用. 不同的代码形式下,绑定的对象代表不同的东西. 下面看一下常见的几种代码形式: 一.独立的函数 function foo() { cons ...

  • 再也不怕 JavaScript 报错了,怎么看怎么处理都在这

    在开发中,有时,我们花了几个小时写的 JS 代码,在游览器调试一看,控制台一堆红,瞬间一万头草泥马奔腾而来.至此,本文主要记录 JS 常见的一些报错类型,以及常见的报错信息,分析其报错原因,并给予处理 ...

  • this 的值到底是什么?一次说清楚

    你可能遇到过这样的 JS 面试题: var obj = { foo: function(){ console.log(this) }}var bar = obj.fooobj.foo() // 打印出 ...

  • 前端面试题整理——Javascript基础

    常见值类型: let a; //undefined let s = 'abc'; let n = 100; let b = true; let sb = Symbol('s'); let nn = N ...

  • es6新增新特性简要总结

    es6简介 es6是在2015年6月正式颁布的新标准,es6基本上实现了所有ECMAScript 规范,以后每年的6月都会发布新版本,但改动不大. let 变量 使用let 关键字来申明的变量拥有以下 ...

  • 基础复习1

    基础回顾1 查找元素位置 题目描述:找出元素 item 在给定数组 arr 中的位置 输出描述: 如果数组中存在 item,则返回元素在数组中的位置,否则返回 -1 function indexOf( ...

  • 一文搞懂 this、apply、call、bind

    "this" 关键字允许在调用函数或方法时决定哪个对象应该是焦点. 在JavaScript中this可以是全局对象.当前对象或者任意对象,这完全取决于函数的调用方式,this 绑定 ...

  • 前端面试题整理——作用域和闭包

    什么是闭包,闭包的表现形式: // 作用域应用的特殊情况,有两种表现: // 函数作为参数被传递 // 函数作为返回值被返回 // 函数作为返回值 function create() { let a ...