资讯专栏INFORMATION COLUMN

es6学习笔记-函数扩展_v1.0_byKL

yuanzhanghu / 2755人阅读

摘要:学习笔记函数扩展函数参数的默认值如果参数默认值是变量,那么参数就不是传值的,而是每次都重新计算默认值表达式的值。属性函数的属性,返回该函数的函数名。箭头函数详细链接参考引用函数扩展

es6学习笔记-函数扩展_v1.0 函数参数的默认值
function Point(x = 0, y = 0) {
    this.x = x;
    this.y = y;
}

var p = new Point();
console.log(p) // { x: 0, y: 0 }

如果参数默认值是变量,那么参数就不是传值的,而是每次都重新计算默认值表达式的值。也就是说,参数默认值是惰性求值的。

let x = 99;
function foo(p = x + 1) {
    console.log(p);
}

foo() // 100

x = 100;
foo() // 101
与解构赋值默认值结合使用
function foo({x, y = 5}) {
    console.log(x, y);
}

foo({}) // undefined, 5,触发默认值
foo({x: 1}) // 1, 5 ,触发默认值
foo({x: 1, y: 2}) // 1, 2
//因为参数是一个对象,对象之后才会解析x y参数
foo() // TypeError: Cannot read property "x" of undefined
//双重默认值,第一重是对象默认值,第二重是对象里面的属性的默认值
function fetch(url, { method = "GET" } = {}) {
    console.log(method);
}
//当触发两重的默认值的时候,会使用最里面的默认值
fetch("http://example.com")
// "GET"
function foo(x = 5, y = 6) {
    console.log(x, y);
}

//undefiend会触发默认值,null则不会
foo(undefined, null)
// 5 null
函数的 length 属性

指定了默认值以后,函数的length属性,将返回没有指定默认值的参数个数。也就是说,指定了默认值后,length属性将失真。

console.log((function (a) {}).length) // 1
console.log((function (a = 5) {}).length) // 0
console.log((function (a, b, c = 5) {}).length) // 2
作用域

一旦设置了参数的默认值,函数进行声明初始化时,参数会形成一个多带带的作用域(context)。等到初始化结束,这个作用域就会消失。这种语法行为,在不设置参数默认值时,是不会出现的。

var x = 1;
//即使x=1,但是没有影响里面的值
function f(x, y = x) {
    console.log(y);
}

f(2) // 2
//---------------------------

let x = 1;
//同理,不过这里是函数里面设置了x值来测试
function f(y = x) {
    let x = 2;
    console.log(y);
}

f() // 1

如果参数的默认值是一个函数,该函数的作用域也遵守这个规则

let foo = "outer";
//设置了一个默认值func,是一个匿名函数,匿名函数返回的是foo变量
//这个变量指向的是外部的foo,因为默认值形成的多带带作用域没有foo,所以会向上层继续找
function bar(func = x => foo) {
    let foo = "inner";
    console.log(func()); // outer
}
//触发默认值,所以输出
bar();
var x = 1;
//y的默认值是一个匿名函数,并且里面设置了x=2,
//这个x是指向参数里的x,他们属于同一个多带带的作用域(默认值生成的)
function foo(x, y = function() { x = 2; }) {
    var x = 3;
    y();//执行y后并没有改变内部函数的x
    console.log(x);//所以输出3
}

foo() // 3
console.log(x) // 1,x没有变化,所以是1
应用

参数的默认值不是在定义时执行,而是在运行时执行(即如果参数已经赋值,默认值中的函数就不会运行)

//参数默认值设为undefined,表明这个参数是可以省略的。
function foo(optional = undefined) { ··· }
rest参数

ES6 引入 rest 参数(形式为“...变量名”),用于获取函数的多余参数,这样就不需要使用arguments对象了。rest 参数搭配的变量是一个数组,该变量将多余的参数放入数组中。

function add(...values) {
    let sum = 0;

    for (var val of values) {
        sum += val;
    }

    return sum;
}
//自动获取了其他参数
console.log(add(2, 5, 3)) // 10
// arguments变量的写法
function sortNumbers() {
  return Array.prototype.slice.call(arguments).sort();
}

// rest参数的写法
const sortNumbers = (...numbers) => numbers.sort();
function push(array, ...items) {//...的是数组
  items.forEach(function(item) {//支持数组的方法forEach
    array.push(item);
    console.log(item);
  });
}

var a = [];
push(a, 1, 2, 3)
扩展运算符

扩展运算符(spread)是三个点(...)。它好比 rest 参数的逆运算,将一个数组转为用逗号分隔的参数序列。(输出结果并没有使用逗号分隔)

console.log(...[1, 2, 3])
// 1 2 3

console.log(1, ...[2, 3, 4], 5)
// 1 2 3 4 5
替代数组的apply方法

由于扩展运算符可以展开数组,所以不再需要apply方法,将数组转为函数的参数了。

// ES5的写法
function f(x, y, z) {
  // ...
}
var args = [0, 1, 2];
f.apply(null, args);

// ES6的写法
function f(x, y, z) {
  // ...
}
var args = [0, 1, 2];
f(...args);
// ES5的写法
Math.max.apply(null, [14, 3, 77])

// ES6的写法
Math.max(...[14, 3, 77])

// 等同于
Math.max(14, 3, 77);
扩展运算符的应用

(1)合并数组

var arr1 = ["a", "b"];
var arr2 = ["c"];
var arr3 = ["d", "e"];

// ES5的合并数组
console.log(arr1.concat(arr2, arr3));
// [ "a", "b", "c", "d", "e" ]

// ES6的合并数组
console.log([...arr1, ...arr2, ...arr3])
// [ "a", "b", "c", "d", "e" ]

(2)与解构赋值结合

const [first, ...rest] = [1, 2, 3, 4, 5];
//位置是对应的
console.log(first) // 1
console.log(rest)  // [2, 3, 4, 5]

const [first, ...rest] = [];
//当没有参数的时候,rest参数能够获取空数组
console.log(first) // undefined
console.log(rest)  // []:

const [first, ...rest] = ["foo"];
//有参数的时候,按顺序
console.log(first)  // "foo"
console.log(rest)   // []

(3)函数的返回值
直接返回多个值

var dateFields = [1,2,3,4,5];
var d = test(...dateFields);
function test(x,y,z,a,b) {
    console.log(x);
    console.log(y);
    console.log(z);
    console.log(a);
    console.log(b);
}
d;

(4)字符串
将字符串转为数组

[..."hello"]
// [ "h", "e", "l", "l", "o" ]

(5)实现了Iterator接口的对象
任何Iterator接口的对象,都可以用扩展运算符转为真正的数组。

在ES6中,有三类数据结构原生具备Iterator接口:数组、某些类似数组的对象、Set和Map结构,但是其他数据结构并没有(主要是对象),需要自己手动设置

(6)Map和Set结构,Generator函数
扩展运算符内部调用的是数据结构的Iterator接口,因此只要具有Iterator接口的对象,都可以使用扩展运算符,比如Map结构。

严格模式

ECMAScript 2016标准》做了一点修改,规定只要函数参数使用了默认值、解构赋值、或者扩展运算符,那么函数内部就不能显式设定为严格模式,否则会报错。

name 属性

函数的name属性,返回该函数的函数名。

箭头函数

详细链接

参考引用:

es6函数扩展

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

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

相关文章

  • es6学习笔记-let,const和块级作用域_v1.0_byKL

    摘要:考虑到环境导致的行为差异太大,应该避免在块级作用域内声明函数。函数声明语句函数表达式循环循环还有一个特别之处,就是循环语句部分是一个父作用域,而循环体内部是一个单独的子作用域。声明一个只读的常量。 es6学习笔记-let,const和块级作用域_v1.0 块级作用域 javascript 原来是没有块级作用域的,只有全局作用域和函数作用域 例子1 因为没有块级作用域,所以每次的i都是一...

    Youngdze 评论0 收藏0
  • es6学习笔记-数值的扩展_V1.0_byKL

    摘要:学习笔记数值的扩展有一些不常用或者还不支持的就没有记录了总体来说本篇只是一个备忘而已用来检查一个数值是否为有限的。两个新方法只对数值有效,非数值一律返回。参考引用数值扩展 es6学习笔记-数值的扩展 有一些不常用或者还不支持的就没有记录了,总体来说本篇只是一个备忘而已 Number.isFinite(), Number.isNaN() Number.isFinite()用来检查一个数值...

    宋华 评论0 收藏0
  • es6学习笔记-字符串的扩展_v1.0_byKL

    摘要:学习笔记字符串的扩展字符的表示法允许使用的形式表示一个字符,但在之前,单个码点仅支持到,超出该范围的必须用双字节形式表示,否则会解析错误。返回布尔值,表示参数字符串是否在源字符串的头部。,是引入了字符串补全长度的功能。 es6学习笔记-字符串的扩展_v1.0 字符的Unicode表示法 JavaScript 允许使用uxxxx的形式表示一个字符,但在 ES6 之前,单个码点仅支持u00...

    JaysonWang 评论0 收藏0
  • es6学习笔记-字符串模板_v1.0_byKL

    摘要:学习笔记字符串模板实例模板编译先组成一个模板使用放置代码使用输出表达式。这被称为标签模板功能。该数组的成员与数组完全一致参考引用字符串扩展 es6学习笔记-字符串模板_v1.0 实例:模板编译 //先组成一个模板 var template = ` //使用放置JavaScript代码 //使用输出JavaScript表达式。 `; //这是编译模板的函数,将模...

    xiongzenghui 评论0 收藏0
  • es6学习笔记-顶层对象_v1.0_byKL

    摘要:学习笔记顶层对象虽然是笔记但是基本是抄了一次大师的文章了顶层对象顶层对象,在浏览器环境指的是对象,在指的是对象。之中,顶层对象的属性与全局变量是等价的。的写法模块的写法上面代码将顶层对象放入变量。参考引用顶层对象实战 es6学习笔记-顶层对象_v1.0 (虽然是笔记,但是基本是抄了一次ruan大师的文章了) 顶层对象 顶层对象,在浏览器环境指的是window对象,在Node指的是gl...

    Meils 评论0 收藏0

发表评论

0条评论

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