es6 - 函数 扩展
1. 可添加默认参数
function fn(name,age=17){ console.log(name+","+age); }
fn("Amy",18); // Amy,18 f
n("Amy",""); // Amy,
fn("Amy"); // Amy,17
注意点:使用函数默认参数时,不允许有同名参数,否则报错;
但是不使用默认参数时,多个同名形参不报错。
只有在未传递参数,或者参数为 undefined 时,才会使用默认参数,null 值被认为是有效的值传递。
在函数体中,不能用let或const再次声明,否则会报错。
函数参数默认值存在暂时性死区,在函数参数默认值表达式中,还未初始化赋值的参数值无法作为其他参数的默认值。
function f(x,y=x){ console.log(x,y); }
f(1); // 1 1
function f(x=y){ console.log(x); }
f(); // ReferenceError: y is not defined
1.1 ES6 之前,不能直接为函数的参数指定默认值,只能采用变通的方法。
function log(x, y) {这种写法的缺点在于,如果参数
y = y || 'World';
console.log(x, y);
}y赋值了,但是对应的布尔值为false,则该赋值不起作用。就像上面代码的最后一行,参数y等于空字符,结果被改为默认值。
为了避免这个问题,通常需要先判断一下参数y是否被赋值,如果没有,再等于默认值。
if (typeof y === 'undefined') {
y = 'World';
}
1.2 与解构赋值的默认值,结合起来使用
function foo({x, y = 5}) {
console.log(x, y);
}
foo({}) // undefined 5
foo({x: 1}) // 1 5
foo({x: 1, y: 2}) // 1 2
foo() // TypeError: Cannot read property 'x' of undefined
2.不定参数 即 传入参数个数可动态
不定参数用来表示不确定参数个数,形如,...变量名,由...加上一个具名参数标识符组成。
具名参数只能放在参数组的最后,并且有且只有一个不定参数。
function f(...values){ console.log(values.length); }
f(1,2); //2
f(1,2,3,4); //4
备注:这里使用不定参数时,'...'是不可替代的,同时使用了...就默认是严格模式,即es6语法环境,
此时再使用es5中hack,则会报错,如想打印传参数量,不能使用 arguments.callee.length argument.length 倒是还可以。
3. 箭头函数 参数 => 函数体
箭头函数有几个使用注意点。
(1)函数体内的this对象,就是定义时所在的对象,而不是使用时所在的对象。
(2)不可以当作构造函数,也就是说,不可以使用new命令,否则会抛出一个错误。
(3)不可以使用arguments对象,该对象在函数体内不存在。如果要用,可以用 rest 参数代替。
(4)不可以使用yield命令,因此箭头函数不能用作 Generator 函数。
3.1 基本用法:
var f = v => v;
//等价于
var f = function(a){
return a;
}
f(1); //1
3.1.1 使用箭头函数前后对比
// 正常函数写法
[1,2,3].map(function (x) {
return x * x;
});
// 箭头函数写法
[1,2,3].map(x => x * x);
3.2 没有参数或者有多个参数
当箭头函数没有参数或者有多个参数,要用 () 括起来。
var f = (a,b) => a+b;
f(6,2); //8
3.3 函数体有多行语句
当箭头函数函数体有多行语句,用 {} 包裹起来,表示代码块,
当只有一行语句,并且需要返回结果时,可以省略 {} , 结果会自动返回。
var f = (a,b) => {
let result = a+b;
return result;
}
f(6,2); // 8
3.4 函数要返回对象
当箭头函数要返回对象的时候,为了区分于代码块,要用 () 将对象包裹起来
var f = (id,name) => ({id: id, name: name});
f(6,2); // {id: 6, name: 2}
3.5 this 对象,是定义函数时的对象
箭头函数体中的 this 对象,是定义函数时的对象,而不是使用函数时的对象。
var name = "The Window";
var object = {
name: "My Object",
getNameFunc: function () {
// this.name = 'change'
// return ()=>this.name var that = this
this.name = 'change'
return function () {
return that.name;
};
}
}; console.log(object.getNameFunc()()) // change
3.5.1 call 借用方法依然成立
function fn(){
setTimeout(()=>{
// 定义时,this 绑定的是 fn 中的 this 对象
console.log(this.a);
},0)
}
var a = 20;
fn.call({a: 18}); // 18
3.5.2 异步回调时,this 指向,不再需要中间变量转换
普通函数
var Person = { 'age': 18, 'sayHello': function () {
setTimeout(function () { console.log(this.age); });
}
};
var age = 20;
Person.sayHello(); // 20
箭头函数
var Person1 = { 'age': 18, 'sayHello': function () {
setTimeout(()=>{ console.log(this.age); });
}
};
var age = 20;
Person1.sayHello(); // 18
经典代码:
debugger
function foo() {
return (a) => {
console.log( this.a );
}; // // return function(a){
// console.log( this.a );
// } //
} var obj1 = {
a: 2
}; var obj2 = {
a: 3
} var bar = foo.call( obj1 );
bar.call( obj2 );
构造函数来创建一个对象,并执行相同的4个show方法
var name = 'window'
function Person (name) {
this.name = name;
this.show1 = function () {
console.log(this.name)
}
this.show2 = () => console.log(this.name)
this.show3 = function () {
return function () {
console.log(this.name)
}
}
this.show4 = function () {
return () => console.log(this.name)
}
}
var personA = new Person('personA')
var personB = new Person('personB')
personA.show1()
personA.show1.call(personB)
personA.show2()
personA.show2.call(personB)
personA.show3()()
personA.show3().call(personB)
personA.show3.call(personB)()
personA.show4()()
personA.show4().call(personB)
personA.show4.call(personB)()
普通复杂场景调用
var name = 'window'
var person1 = {
name: 'person1',
show1: function () {
console.log(this.name)
},
show2: () => console.log(this.name),
show3: function () {
return function () {
console.log(this.name)
}
},
show4: function () {
return () => console.log(this.name)
}
}
var person2 = { name: 'person2' }
person1.show1()
person1.show1.call(person2)
person1.show2()
person1.show2.call(person2)
person1.show3()()
person1.show3().call(person2)
person1.show3.call(person2)()
person1.show4()()
person1.show4().call(person2)
person1.show4.call(person2)()
3.5.3 this 定义在箭头函数中,容易形成误导,因为此时的this指向window,而不是函数或者方法所属对象(区别于动态回调,这种场景推荐使用原来的普通函数)
var Person = { 'age': 18, 'sayHello': ()=>{ console.log(this.age); } };
var age = 20;
Person.sayHello(); // 20 // 此时 this 指向的是全局对象
var Person1 = { 'age': 18, 'sayHello': function () { console.log(this.age); } };
var age = 20;
Person1.sayHello(); // 18 // 此时的 this 指向 Person1 对象
3.5.3.1 需要动态 this 的时候
var button = document.getElementById('userClick'); button.addEventListener('click', () => { this.classList.toggle('on'); });
button 的监听函数是箭头函数,所以监听函数里面的 this 指向的是定义的时候外层的 this 对象,即 Window,导致无法操作到被点击的按钮对象。
4. 函数的length属性 length属性的返回值,等于指定了默认值的参数 之前的参数个数。
(function (a) {}).length // 1
(function (a = 5) {}).length // 0
(function (a, b, c = 5) {}).length // 2(function(...args) {}).length // 0
如果设置了默认值的参数不是尾参数,那么length属性也不再计入后面的参数了。
(function (a = 0, b, c) {}).length // 0
(function (a, b = 1, c) {}).length // 1
es6 - 函数 扩展的更多相关文章
- ES6函数扩展
前面的话 函数是所有编程语言的重要组成部分,在ES6出现前,JS的函数语法一直没有太大的变化,从而遗留了很多问题和的做法,导致实现一些基本的功能经常要编写很多代码.ES6大力度地更新了函数特性,在ES ...
- 深入理解javascript函数系列第四篇——ES6函数扩展
× 目录 [1]参数默认值 [2]rest参数 [3]扩展运算符[4]箭头函数 前面的话 ES6标准关于函数扩展部分,主要涉及以下四个方面:参数默认值.rest参数.扩展运算符和箭头函数 参数默认值 ...
- 函数——es6函数扩展(二)
一.声明 1. let(变量) 可以只声明不给值(默认为undefined),或者是先声明后给值,但是必需声明后再使用,可以重复赋值,可以防止变量泄露: 同一作用域里不能重复的声明,不同作用域里可以, ...
- ES6 - 函数扩展(函数参数默认值)
函数参数默认值 ES6 之前,不能直接为函数的参数指定默认值,只能采用变通的方法. function log(x, y) { y = y || 'World'; console.log(x, y); ...
- es6函数扩展(+ ...扩展运算符)
1.参数默认值 function foo(param = 'nihao'){ console.log(param); } foo('hello kitty'); 2.参数解构赋值 function f ...
- ES6 函数的扩展2
8.2 rest参数 ES6引入rest参数(形式为"-变量名"),用于获取函数的多余参数,这样就不需要使用arguments对象了. arguments对象并没有数组的方法,re ...
- es6之函数扩展与对象扩展
一.函数扩展 1.参数默认值 参数有默认值,后面不可以再加没有默认值的变量.如以下test函数中,不可以加写成 function test(x,y="word",z){ } fun ...
- 04 | 函数扩展 | es6
函数参数的默认值 基本用法 ES6 之前,不能直接为函数的参数指定默认值,只能采用变通的方法. function log(x, y) { y = y || 'World'; console.log(x ...
- es6 入坑笔记(二)---函数扩展,箭头函数,扩展运算符...
函数扩展 1.函数可以有默认值 function demo( a = 10,b ){} 2.函数可以使用解构 function demo( { a = 0,b = 0 } = {} ){ } 3.函数 ...
随机推荐
- 设置PhoenixOS进入图形界面
phoenix操作系统很淡疼的一点就是每次启动都进入命令行界面,而且要想进入图形界面,每次都得配置. 开启虚拟机后,会出现引导界面,在虚拟机中连按2次“E”键进行编辑 输入参数“空格nomodeset ...
- oracle 11g enq: JI – contention等待事件
最近使用物化视图同步的环境在大量刷新的时候频繁出现enq: JI – contention等待事件,经查: JI enqueue is acquired in exclusive mode on th ...
- Bitbucket备份恢复
我们需要备份什么? home directory:contains repository data, log files, plugins, and so on. database:contains ...
- centos7 yum install timeout
https://yum.dockerproject.org/repo/main/centos/7/repodata/repomd.xml: [Errno 12] Timeout on https:// ...
- VC++ 利用PDB和dump文件定位问题并进行调试
转载:https://blog.csdn.net/zfs_kuai/article/details/43646665 转载:https://blog.csdn.net/i_chaoren/articl ...
- 尚硅谷面试第一季-14Redis持久化类型及其区别
课堂重点: Redis提供了两种不同形式的持久化方案,分别是RDB和AOF. RDB使用Snapshot快照做全量的存储. RDB优缺点: AOF 以日志的方式记录每个写操作,只最佳,不该写文件.增量 ...
- python&django 常见问题及解决方法
0.python-dev安装(ubuntu) apt-get install python-dev 1.Open(filename,mode) 报错实例: f = open('d:\Users\16 ...
- bzoj1566: [NOI2009]管道取珠 DP
题目链接 https://www.lydsy.com/JudgeOnline/problem.php?id=1566 思路 n个球,第i个球颜色为ai,对于颜色j,对答案的贡献为颜色为j的球的个数的平 ...
- 解决Visual Studio(2017)软件无法重新生成问题
https://blog.csdn.net/qq_38265674/article/details/80539228 笔者用VS2017打开VS2015创建的工程,出现如下图的问题. 不小心没有升级平 ...
- FJUT3591 侦测到在途的聚变打击(最小不可相交路径覆盖)题解
题意:给你n个点,点间m条路,给出在每条路要走的时间.现在有q个任务,要摧毁q个点,每次提供ci和ti表示在时间ti摧毁点ci(必须正好在时间ti才能摧毁),每个点可能需要多次摧毁(同一时间能在同一个 ...