ref:《重学前端》
有多少种函数
第一种,普通函数:用function关键字定义的函数
function foo(){
// code
}
第二种,箭头函数:用 => 运算符定义的函数
const foo = () => {
// code
}
第三种,方法:在class中定义的函数
class C {
foo(){
//code
}
}
第四种,生成器函数:用function * 定义的函数
function* foo(){
// code
}
第五种,类:用class定义的类,实际上也是函数
class Foo {
constructor(){
//code
}
}
第六/七/八种,异步函数:普通函数、箭头函数和生成器函数加上async关键字
async function foo(){
// code
}
const foo = async () => {
// code
}
async function foo*(){
// code
}
this关键字
this是执行上下文中很重要的一个组成部分。同一个函数调用方式不同,得到的this值也不同
function showThis(){
console.log(this);
}
var o = {
showThis: showThis
}
showThis(); // global
o.showThis(); // o
调用函数时使用的引用,决定了函数执行时刻的this值
换成箭头函数,结果就不一样了:
const showThis = () => {
console.log(this);
}
var o = {
showThis: showThis
}
showThis(); // global
o.showThis(); // global
我们看到,改为箭头函数后,不论用什么引用来调用它,都不影响它的this值
接下来我们看看“方法”,它的行为又不一样了:
class C {
showThis() {
console.log(this);
}
}
var o = new C();
var showThis = o.showThis;
showThis(); // undefined
o.showThis(); // o
这里我们创建了一个类C,并且实例化出对象o,再把o的方法赋值给了变量showThis。
这时候,我们使用showThis这个引用去调用方法时,得到了undefined。
所以,在方法中,我们看到this的行为也不太一样,它得到了undefined的结果
按照我们上面的方法,不难验证出:生成器函数、异步生成器函数和异步普通函数跟普通函数行为是一致的,异步箭头函数与箭头函数行为是一致的。
imp==>
方法的行为跟普通函数有差异,恰恰是因为class设计成了默认按strict模式执行。
我们可以用strict达成与上面方法的例子一样的效果:
"use strict"
function showThis(){
console.log(this);
}
var o = {
showThis: showThis
}
showThis(); // undefined
o.showThis(); // o
嵌套的箭头函数中的代码都指向外层this
var o = {}
o.foo = function foo(){
console.log(this);
return () => {
console.log(this);
return () => console.log(this);
}
}
o.foo()()(); // o, o, o
操作this的内置函数
Function.prototype.call 和 Function.prototype.apply 可以指定函数调用时传入的this值,示例如下:
function foo(a, b, c){
console.log(this);
console.log(a, b, c);
}
foo.call({}, 1, 2, 3);
foo.apply({}, [1, 2, 3]);
这里call和apply作用是一样的,只是传参方式有区别
此外,还有 Function.prototype.bind 它可以生成一个绑定过的函数,这个函数的this值固定了参数:
function foo(a, b, c){
console.log(this);
console.log(a, b, c);
}
foo.bind({}, 1, 2, 3)();
call、bind和apply用于不接受this的函数类型如箭头、class都不会报错。
这时候,它们无法实现改变this的能力,但是可以实现传参.
ref:《重学前端》
有多少种函数
第一种,普通函数:用function关键字定义的函数
第二种,箭头函数:用 => 运算符定义的函数
第三种,方法:在class中定义的函数
第四种,生成器函数:用function * 定义的函数
第五种,类:用class定义的类,实际上也是函数
第六/七/八种,异步函数:普通函数、箭头函数和生成器函数加上async关键字
this关键字
this是执行上下文中很重要的一个组成部分。同一个函数调用方式不同,得到的this值也不同
调用函数时使用的引用,决定了函数执行时刻的this值
换成箭头函数,结果就不一样了:
我们看到,改为箭头函数后,不论用什么引用来调用它,都不影响它的this值
接下来我们看看“方法”,它的行为又不一样了:
这里我们创建了一个类C,并且实例化出对象o,再把o的方法赋值给了变量showThis。
这时候,我们使用showThis这个引用去调用方法时,得到了undefined。
所以,在方法中,我们看到this的行为也不太一样,它得到了undefined的结果
按照我们上面的方法,不难验证出:生成器函数、异步生成器函数和异步普通函数跟普通函数行为是一致的,异步箭头函数与箭头函数行为是一致的。
imp==>
方法的行为跟普通函数有差异,恰恰是因为class设计成了默认按strict模式执行。
我们可以用strict达成与上面方法的例子一样的效果:
嵌套的箭头函数中的代码都指向外层this
操作this的内置函数
Function.prototype.call 和 Function.prototype.apply 可以指定函数调用时传入的this值,示例如下:
这里call和apply作用是一样的,只是传参方式有区别此外,还有 Function.prototype.bind 它可以生成一个绑定过的函数,这个函数的this值固定了参数:
call、bind和apply用于不接受this的函数类型如箭头、class都不会报错。
这时候,它们无法实现改变this的能力,但是可以实现传参.