什么是词法作用域?

845

什么是词法作用域的简要介绍?


107
在第58期播客中,Joel鼓励这样的问题,因为他希望SO成为回答问题的“唯一之地”,即使这些问题已经在其他地方得到了回答。这是一个有效的问题,尽管可以更礼貌地提出它。 - malach
18
可能这个提问者在撰写这个问题时不是(或曾经不是)英语流利的。 - xyhhx
50
问题很客气,他只是说出了自己想要的。你可以自由回答,这里不需要过于敏感的礼貌用语。 - Markus Siebeneicher
38
我认为像这样的问题非常好,因为它们为SO建立了内容。在我看来,如果问题没有付出努力,也无所谓... 因为答案将有很棒的内容,这才是这个留言板上最重要的。 - Jwan622
10
我同意@Jwan622的观点,一个好问题不需要冗长,简洁明了也可以。 - Andrew
显示剩余2条评论
22个回答

0

这个主题与内置的bind函数密切相关,是在ECMAScript 6 箭头函数中引入的。这真的很烦人,因为对于每个新的“类”(实际上是函数)方法,我们都必须bind它,以便访问作用域。

默认情况下,JavaScript不会将其this的范围设置为函数(它不会在this上设置上下文)。默认情况下,您必须明确说明要使用哪个上下文

箭头函数会自动获取所谓的词法作用域(可以访问其包含块中变量的定义)。当使用箭头函数时,它会自动将this绑定到箭头函数在第一次定义的位置,并且此箭头函数上下文是其包含块。

请看下面最简单的示例,了解它的工作原理。

在使用箭头函数之前(默认情况下没有词法作用域):

const programming = {
  language: "JavaScript",
  getLanguage: function() {
    return this.language;
  }
}

const globalScope = programming.getLanguage;
console.log(globalScope()); // Output: undefined

const localScope = programming.getLanguage.bind(programming);
console.log(localScope()); // Output: "JavaScript"

使用箭头函数(默认为词法作用域):

const programming = {
  language: "JavaScript",
  getLanguage: function() {
    return this.language;
  }
}

const arrowFunction = () => {
    console.log(programming.getLanguage());
}

arrowFunction(); // Output: "JavaScript"

-1

我通常通过示例学习,这里有一个小例子:

const lives = 0;

function catCircus () {
    this.lives = 1;
    const lives = 2;

    const cat1 = {
        lives: 5,
        jumps: () => {
            console.log(this.lives);
        }
    };
    cat1.jumps(); // 1
    console.log(cat1); // { lives: 5, jumps: [Function: jumps] }

    const cat2 = {
        lives: 5,
        jumps: () => {
            console.log(lives);
        }
    };
    cat2.jumps(); // 2
    console.log(cat2); // { lives: 5, jumps: [Function: jumps] }

    const cat3 = {
        lives: 5,
        jumps: () => {
            const lives = 3;
            console.log(lives);
        }
    };
    cat3.jumps(); // 3
    console.log(cat3); // { lives: 5, jumps: [Function: jumps] }

    const cat4 = {
        lives: 5,
        jumps: function () {
            console.log(lives);
        }
    };
    cat4.jumps(); // 2
    console.log(cat4); // { lives: 5, jumps: [Function: jumps] }

    const cat5 = {
        lives: 5,
        jumps: function () {
            var lives = 4;
            console.log(lives);
        }
    };
    cat5.jumps(); // 4
    console.log(cat5); // { lives: 5, jumps: [Function: jumps] }

    const cat6 = {
        lives: 5,
        jumps: function () {
            console.log(this.lives);
        }
    };
    cat6.jumps(); // 5
    console.log(cat6); // { lives: 5, jumps: [Function: jumps] }

    const cat7 = {
        lives: 5,
        jumps: function thrownOutOfWindow () {
            console.log(this.lives);
        }
    };
    cat7.jumps(); // 5
    console.log(cat7); // { lives: 5, jumps: [Function: thrownOutOfWindow] }
}

catCircus();

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接