Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

JavaScript执行:函数、this #9

Open
K-Kevin opened this issue Oct 31, 2019 · 0 comments
Open

JavaScript执行:函数、this #9

K-Kevin opened this issue Oct 31, 2019 · 0 comments

Comments

@K-Kevin
Copy link
Owner

K-Kevin commented Oct 31, 2019

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的能力,但是可以实现传参.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant