词汇范围的简要介绍是什么?
当前回答
我通常通过举例学习,这里有一点小意思:
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();
其他回答
让我们尝试最短的定义:
词法作用域定义了如何在嵌套函数中解析变量名:即使父函数已返回,内部函数也包含父函数的作用域。
这就是它的全部!
作用域是可访问变量/绑定的上下文。词法范围是指封闭词法块的局部范围,而不是全局范围。
我喜欢@Arak这样的人提供的功能齐全、语言不可知的答案。由于这个问题被标记为JavaScript,所以我想插入一些与该语言非常相关的注释。
在JavaScript中,我们的作用域选择如下:
按原样(无范围调整)词法var_this=this;函数callback(){console.log(_this);}绑定回调.bind(this)
我认为值得注意的是,JavaScript并没有真正的动态范围。bind调整this关键字,这很接近,但在技术上并不相同。
下面是一个示例,演示了这两种方法。每次决定如何确定回调的范围时,都要这样做,因此这适用于承诺、事件处理程序等。
词汇
以下是JavaScript中回调的词法范围:
var downloadManager = {
initialize: function() {
var _this = this; // Set up `_this` for lexical access
$('.downloadLink').on('click', function () {
_this.startDownload();
});
},
startDownload: function(){
this.thinking = true;
// Request the file from the server and bind more callbacks for when it returns success or failure
}
//...
};
跳跃
作用域的另一种方法是使用Function.prototype.bind:
var downloadManager = {
initialize: function() {
$('.downloadLink').on('click', function () {
this.startDownload();
}.bind(this)); // Create a function object bound to `this`
}
//...
据我所知,这些方法在行为上是等效的。
围绕词汇和动态作用域的对话中有一个重要的部分是缺失的:作用域变量的生存期或何时可以访问变量的简单解释。
动态范围界定与“全局”范围界定在我们传统的思考方式中只是非常松散地对应(我之所以将两者进行比较,是因为已经提到了这一点——我并不特别喜欢链接文章的解释);我们最好不要在全局变量和动态变量之间进行比较,尽管根据链接文章的说法,“……[它]作为全局范围变量的替代品很有用。”
那么,用简单的英语来说,这两种范围界定机制之间的重要区别是什么?
在上面的答案中,词汇范围定义得很好:词汇范围变量在定义它的函数的本地级别是可用的,或者是可访问的。
然而,由于它不是OP的重点,动态范围界定并没有得到太多的关注,它得到的关注意味着它可能需要更多的关注(这不是对其他答案的批评,而是“哦,那个答案让我们希望有更多的关注”)。所以,这里还有一点:
动态作用域意味着在函数调用的生命周期内,或在函数执行时,较大的程序可以访问变量。实际上,维基百科在解释两者之间的差异方面做得很好。为了避免混淆,下面是描述动态范围的文本:
…[I]n动态作用域(或动态作用域),如果变量名的作用域是则其范围是函数正在执行:当函数运行时,变量name存在,并绑定到其变量,但在函数之后返回,变量名不存在。
本主题与内置绑定函数密切相关,并在ECMAScript 6 Arrow函数中介绍。这真的很烦人,因为对于我们想要使用的每一个新的“类”(实际上是函数)方法,我们都必须绑定它才能访问作用域。
默认情况下,JavaScript不会在函数上设置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"
推荐文章
- 如何在Typescript中解析JSON字符串
- Javascript reduce()在对象
- 在angularJS中& vs @和=的区别是什么
- 错误"Uncaught SyntaxError:意外的标记与JSON.parse"
- JavaScript中的querySelector和querySelectorAll vs getElementsByClassName和getElementById
- 给一个数字加上st, nd, rd和th(序数)后缀
- 如何以编程方式触发引导模式?
- setTimeout带引号和不带括号的区别
- 在JS的Chrome CPU配置文件中,'self'和'total'之间的差异
- 用javascript检查输入字符串中是否包含数字
- 如何使用JavaScript分割逗号分隔字符串?
- 在Javascript中~~(“双波浪号”)做什么?
- 谷歌chrome扩展::console.log()从后台页面?
- 未捕获的SyntaxError:
- [].slice的解释。调用javascript?