js中的函数
本质
函数实际上是一个Function
对象
函数不定义return
默认返回undefined
定义函数方法
有多种方法可以定义函数
函数声明(函数语句)
1 |
|
函数表达式
函数表表达式可以看作是把函数作为值的一种用法
1 |
|
把函数传给变量,常量当值是函数表达式,传给函数当参数值也是函数表达式
❓:那为什么要具名定义函数呢,既然赋值给变量了,那都写成function (){}
不就好了
💡:因为有时会定义递归函数,像是这样
1 |
|
在写法上这两种非常行接近,区别重要在提升和作用域方面
- 函数声明定义的函数是可以在定义前调用的,因为在执行前会被提升到当前作用域的顶部,相对的函数表达式不会提升,所以在定义前调用会报错
函数生成器声明
函数生成器表达式
箭头函数表达式
写法
1 |
|
其中括号中的是参数,支持剩余参数、默认参数和解构,始终需要括号
- 剩余参数
1 |
|
其中a
、b
是普通参数,...r
表示接受剩余的所有参数,组成一个数组
- 默认参数
当函数未传入对应参数或是传入undefined
时,他将会使用默认的值
1 |
|
只有undefined
可以,其余的假值是不起作用的
把带默认值的参数放到前面再试图跳过他是不合法的,像是这样
1 |
|
但可以把带默认值的参数放到最后
1 |
|
解构赋值
数组解构
- 基本用法
1
2
3
4
5const arr = [1, 2, 3];
const [a, b, c] = arr;
console.log(a); // 1
console.log(b); // 2
console.log(c); // 3- 跳过元素
1
2const [x, , z] = [10, 20, 30];
console.log(x, z); // 10 30- 默认值
1
2const [a = 100, b = 200] = [1];
console.log(a, b); // 1 200- 嵌套解构
1
2const [a, [b, c]] = [1, [2, 3]];
console.log(a, b, c); // 1 2 3
箭头函数没有独立的 this
、arguments
和 super
绑定,并且不可被用作方法。
this
的值取决于它出现的上下文:函数、类或全局
函数上下文
在函数内部,this 的值取决于函数如何被调用,this
的值不是拥有此函数作为自己属性的对象,而是用于调用此函数的对象。1
2
3
4
5
6
7
8
9const obj4 = {
name: "obj4",
getThis() {
return this;
},
};
const obj5 = { name: "obj5" };
obj6.getThis = obj4.getThis;
console.log(obj5.getThis()); // { name: 'obj5', getThis: [Function: getThis] }普通函数的
this
是‘调用时决定的’,而箭头函数的this
是‘定义时决定的’,永远集成自外层作用域,不能改变1
2
3
4
5
6
7
8
9
10
11const obj = {
name: "Alice",
sayHi1: function () {
console.log(this.name); // this 指向 obj,输出 "Alice"
},
sayHi2: () => {
console.log(this.name); // this 不是 obj,而是外部(window/undefined)
},
};
obj.sayHi1(); // "Alice"
obj.sayHi2(); // undefined(不是你期望的)上面的
obj
只是一个变量对象,箭头函数从他那里得不到this
,只能再往上,也就是全局
arguments
同样从上层继承事实上只有函数,arguments
是一个对应于传递给函数的参数的类数组对象。
在官方文档中,推荐编写兼容ES6的代码时使用剩余参数
super
从它被定义的上下文获取包含它的类
这三个东西,都要从外层作用域继承,是因为ES6设计箭头函数时,目的就是简洁、闭包友好、绑定外层this,因此:
- 它不创建自己的执行上下文
- 它直接使用它定义时的“父作用域”的上下文。
- 所以,它也就没有自己的
this
、arguments
、super
、new.target
。
Function
构造函数
–TODO: 续写
1 |
|