资讯专栏INFORMATION COLUMN

ES6 札记:函数

CoreDump / 436人阅读

摘要:所以,当函数传参为时,短路操作符会给定默认值。对于来说,无论是否在严格模式下,更改参数值的行为都不会同步更改对象。且箭头函数中的值无法改变而非箭头函数也正因为如此,箭头函数无法作为构造函数,因为值无法绑定至构造函数的实例。

如同我们所看到的,ES6 中引入来箭头函数,相比 ES5 来讲是最为直观而明显的特性。

在 ES6 之前,声明一个函数:

function add(a, b) {
  return a + b;
}
add(1, 2); // 3

如果用箭头函数的形式写:

const add = (a, b) => a + b;
add(1, 2); // 3

计算圆面积的例子:

const square = (r) => {
  const PI = 3.14;
  return PI*r*r;
}
square(4);

形式上的改变仅仅是一部分,接下来关注一个很有用的特性:默认值。

默认值

在 ES6 之前,函数内给定参数的默认值,只能这样:

function add(a, b) {
  console.log(arguments[0]);
  a = a || 2000;
  b = b || 333;
  return a + b;
}
add(); // 2333

但是此方案遇到 boolean 为 false 的 js 值无法工作,例如:

add(0); // 2333

显然,结果错误。运算中 a 仍旧采用了默认值。

所以,当函数传参为 null, undefined, "", 0, -0, NaN 时,短路操作符 || 会给定默认值。

修订版成了这样:

function add(a, b) {
  a = (typeof a !== "undefined") ? a : 2000;
  b = (typeof b !== "undefined") ? b : 333;
  return a + b;
}
add(0); // 333

而在 ES6 中,只需要给参数直接赋予默认值即可:

const add = (a = 2000, b = 333) => a + b;
add(); // 2333
add(0); // 333
默认值对 arguments 的影响

在 ES5 中:

function add(a, b) {
  console.log(arguments.length);
  console.log(a === arguments[0]);
  console.log(b === arguments[1]);
  a = 200;
  b = 33;
  console.log(a === arguments[0]);
  console.log(b === arguments[1]);
}
add(1, 2);
// 2
// true
// true
// true
// true

如果在严格模式下运行,结果是这样的:

function add(a, b) {
  "use strict";
  console.log(arguments.length);
  console.log(a === arguments[0]);
  console.log(b === arguments[1]);
  a = 200;
  b = 33;
  console.log(a === arguments[0]);
  console.log(b === arguments[1]);
}
add(1, 2);
// 2
// true
// true
// false
// false

在 ES5 中的非严格模式下,更改参数值将会同步的更改 arguments 对象内的参数值,而在严格模式下不会更改。

对于 ES6 来说,无论是否在严格模式下,更改参数值的行为都不会同步更改 arguments 对象。

function add(a = 2000, b = 333) {
  console.log(arguments.length);
  console.log(a === arguments[0]);
  console.log(b === arguments[1]);
  a = 200;
  b = 33;
  console.log(a === arguments[0]);
  console.log(b === arguments[1]);
}
add(0);
// 1
// true
// false
// false
// false

再来看个例子:

const add = (a = 2000, b = 333) => {
  console.log(arguments.length);
  console.log(a === arguments[0]);
  console.log(b === arguments[1]);
  a = 200;
  b = 33;
  console.log(a === arguments[0]);
  console.log(b === arguments[1]);
}
add(0);
// Uncaught ReferenceError: arguments is not defined

另外需要注意的点是,箭头函数没有自己的 arguments 对象。但它可以访问外围函数的 arguments 对象:

function add(a = 2000, b = 333) {
  return (() => arguments[0] + arguments[1])();
}
add(); // NaN
add(200, 33); // 233
this

在 ES6 的箭头函数中,this 值总是绑定到函数的定义:

const obj = {
  name: "Rainy",
  say: function () {
    setTimeout(() => {
      console.log(`I"m ${this.name}`);
    })
  }
}
obj.say(); // I"m Rainy

而如果是普通函数,由于 setTimeout 函数内的 this 指向 window,所以找不到 name 值:

const obj = {
  name: "Rainy",
  say: function () {
    setTimeout(function () {
      console.log(`I"m ${this.name}`);
    })
  }
}
obj.say(); // I"m

可以将箭头函数的该行为看作:

const obj = {
  name: "Rainy",
  say: function () {
    const self = this;
    setTimeout(function () {
        console.log(`I"m ${self.name}`);
    })
  }
}
obj.say(); // I"m Rainy

实际上这是由于箭头函数本身没有 this,其中的 this 实际上是外部函数的 this 绑定。

且箭头函数中的 this 值无法改变:

const obj = {
  name: "Rainy",
  say: function () {
    setTimeout((() => console.log(`I"m ${this.name}`)).bind({name: "Null"}))
  }
}
obj.say(); // I"m Rainy

而非箭头函数:

const obj = {
  name: "Rainy",
  say: function () {
    setTimeout((function () {console.log(`I"m ${this.name}`)}).bind({name: "Null"}))
  }
}
obj.say(); // I"m Null

也正因为如此,箭头函数无法作为构造函数,因为 this 值无法绑定至构造函数的实例。

参考

《深入理解 ES6》

《实战 ES2015》

MDN

-EOF-

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/94952.html

相关文章

  • ES6 札记:let 和 const

    摘要:在之前,中没有常量声明方式,有的仅仅是一种命名上的约定。这样就可以最大程度上规避变量的意外变化来使程序发生异常的可能性。为了避免作用域的污染,在中需要使用一个立即执行函数来确保变量的作用域范围。 在 ES6 之前,JS 中没有常量声明方式,有的仅仅是一种命名上的约定。 var PI = 3.14; PI = 4; console.log(PI); // 4 我们用大写变量名来标识这是一...

    bluesky 评论0 收藏0
  • JS 异步系列 —— Promise 札记

    摘要:以下,请求两个,当两个异步请求返还结果后,再请求第三个此处为调用后的结果的数组对于来说,只要参数数组有一个元素变为决定态,便返回新的。 showImg(https://segmentfault.com/img/remote/1460000015444020); Promise 札记 研究 Promise 的动机大体有以下几点: 对其 api 的不熟悉以及对实现机制的好奇; 很多库(比...

    zhouzhou 评论0 收藏0
  • ES6常用知识学习札记

    摘要:在年正式发布了,简称,又称为。再次简写循环迭代数组每个元素都执行一次回调函数。方法用于调用数组的每个元素,并将元素传递给回调函数。注意对于空数组是不会执行回调函数的。 转载请注明出处 原文连接 http://blog.huanghanlian.com/article/5c7aa6c7bf3acc0864870f9d es6 是什么 首先弄明白ECMA和js的关系。ECMA是标准,Jav...

    googollee 评论0 收藏0
  • ES6常用知识学习札记

    摘要:在年正式发布了,简称,又称为。再次简写循环迭代数组每个元素都执行一次回调函数。方法用于调用数组的每个元素,并将元素传递给回调函数。注意对于空数组是不会执行回调函数的。 转载请注明出处 原文连接 http://blog.huanghanlian.com/article/5c7aa6c7bf3acc0864870f9d es6 是什么 首先弄明白ECMA和js的关系。ECMA是标准,Jav...

    tracymac7 评论0 收藏0
  • CSS札记(一):CSS选择器

    一、语法规则 选择器{ 属性1:属性值1; 属性2:属性值2; ...... } /*注释*/ 二、如何在html中应用CSS 1. 外部引用css文件 css文件:css/layout.css(css文件夹和HTML位于同一个目录下) 2. 内部嵌入css /*css代码*/ 3...

    yzzz 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<