JAVASCRIPT中的可变范围
级别:初级/中级([支架]中的中级填充)
先决条件:变量
首先,到底什么是“范围”(那种无助于杀死引起口臭的细菌)? 范围描述了可以使用变量的上下文。 例如,如果变量的范围是某个函数,则该变量只能在该函数中使用。 如果要尝试在脚本中的其他任何位置访问该变量,则它将以未定义的形式返回。
javascript中有四种(技术上是三种)范围类型
:- window-这些变量可以随时在脚本中的任何位置使用。
- 函数-这些变量仅在特定函数内部可用。
- class(可以说与函数相同)-这些变量仅适用于特定类的成员。
- 块(JavaScript 1.7中的新增功能)-这些变量仅存在于特定的代码块内(即,在一组'{'和'}'之间)。
窗口级变量将附加到脚本中的通用窗口对象。 要声明窗口级(或“全局”)变量,可以使用以下语法:
<script type="text/javascript">
var myGlobal = "This is a global variable because it's not declared inside a function.";
myGlobal = "This is also a global variable because it is not defined using the 'var' keyword. See below for more info.";
window.myGlobal = 'This is also global for the same reason the previous statement is global.';
</script>
var关键字将变量绑定到其父上下文。
如果在函数或对象外部使用var关键字声明变量,则该变量是全局变量,因为默认上下文是window。
所以:
var myGlobal = 'This is global because my context is window, but...';
function doSomething() {
var myLocal = '... this is not because my context is doSomething, not window.';
}
如果您不使用var关键字,浏览器也会自动将变量设为全局变量。
发生这种情况的原因与您可以使用“ location.href”而不是“ window.location.href”的原因相同。
[中间文件:JavaScript有一个(很少使用的)'with'关键字,可让您随意定义上下文。
使用with关键字定义上下文时,可以在访问父对象时省略其父对象。
例如:
var myObject = {
product: 'paper',
quantity: 500,
salesman: 'Fred'
};
with(myObject) {
alert(salesman);
}
上面的代码将警告“ Fred”。
同样,JavaScript中的每个脚本都以以下(隐含的)语句开头:
with(window) {
// Your code goes here.
}
在此处可以正确使用'with'关键字(以及为什么几乎从未使用过)。
就像这两个语句完全一样:
window.location.href = 'http://www.example.com/';
location.href = 'http://www.example.com/';
这些语句是否相同:
window.myVar = 'Global variable!';
myVar = 'Also global!';
顺便说一句,由于每个浏览器窗口(或选项卡)只有一个窗口实例,因此,页面中包含的任何脚本都可以访问任何全局变量。
全局变量不限于单个<SCRIPT>块,您甚至可以在一个.js文件中声明一个全局变量,然后在另一个.js文件中访问它(尽管您可能要检查以确保它先存在)!
功能/类的范围 [中间的东西:我将函数和类混为一谈,因为类基本上就是JavaScript中真正非常闪亮的函数。]
这就是var关键字真正变得重要的地方。 请记住,在“窗口范围”部分,var关键字会将变量绑定到其父上下文:
<script type="text/javascript">
var myGlobal = 'Global because my context is window.';
function doSomething() {
var myLocal = 'Not global because my context is doSomething, not window.';
}
</script>
由于我们使用var在doSomething内部声明变量“ myLocal”,因此我们将myLocal绑定到doSomething的上下文。
换一种说法:
function doSomething() {
var myLocal = 'Not a global variable.';
alert(myLocal);
}
doSomething(); // Alerts 'Not a global variable.'.
alert(myLocal); // Alerts 'undefined'.
如果要使myLocal为全局,我们可以简单地删除var关键字:
function doSomething() {
myLocal = 'This is global because it gets attached to window.';
alert(myLocal);
}
doSomething(); // Alerts 'This is global because it gets attached to window.'.
alert(myLocal); // Alerts 'This is global because it gets attached to window.'.
[中间文件:同样,您可以使用var关键字将局部变量绑定到类的上下文。
顺便说一下,这就是在JavaScript类中实现私有变量的方式:
function Class() {
var myPrivate;
function __construct() {
myPrivate = 'A private variable.';
alert(myPrivate);
}
__construct();
}
var myObject = new Class(); // Alerts 'A private variable.'.
alert(myObject.myPrivate); // Alerts 'undefined' because myPrivate is not a member of myObject.
为什么这样做?
请参见下面的“范围继承”。] 范围(JAVASCRIPT 1.7中的新增功能)
let关键字是JavaScript 1.7中的新功能(明白吗?)。 let允许您将变量的作用域限定为特定的代码块。
例如:
let(myVar = 5) {
alert(myVar); // Alerts 5.
}
alert(myVar); // Alerts 'undefined'.
由于JavaScript 1.7尚不支持所有浏览器,因此建议您暂时不要使用let关键字。
但这很有趣!
有关JavaScript 1.7的更多信息,请查看
这个文件 。 范围继承因此,我们知道您可以使用范围界定将对变量的访问限制为特定的上下文。 但是函数或类内部的函数(上下文)呢? 范围界定如何工作?
让我们看一个示例设置:
function myOuterFunction() {
var myLocal = 'Declared locally.';
function myInnerFunction() {
alert(myLocal);
}
myInnerFunction(); // Alerts 'Declared locally.'
}
myOuterFunction(); // To declare myInnerFunction...
myInnerFunction(); // Generates an error (see below).
请注意,在上面的示例中,由于myInnerFunction是在myOuterFunction内部声明的,因此它可以访问所有myOuterFunction的变量。
[中间文件:还请注意,myInnerFunction附加到myOuterFunction的上下文。
换句话说,如果尝试在myOuterFunction之外调用myInnerFunction,则会收到错误消息。
其原因与在myOuterFunction之外未定义myLocal变量的原因相同。 有关更多信息,请参阅本文 。] 处理冲突
如果在重叠的上下文中具有相同名称的两个变量会发生什么?
var myVar = 'Global';
alert(myVar); // Alerts 'Global'.
function myOuterFunction() {
var myVar = 'Local';
alert(myVar); // Alerts 'Local'.
function myInnerFunction(myVar) {
myVar = myVar + '!';
alert(myVar);
}
myInnerFunction('Inner'); // Alerts 'Inner!'.
}
myOuterFunction(); // Do we modify myVar?
alert(myVar); // Alerts 'Global'.
当您在给定上下文中声明变量时,该变量将替换具有该名称的所有其他可用变量。
它不会覆盖它们。
它仅使用局部变量而不是全局变量(或父变量)。
这就是为什么上例中的最终警报语句输出“ Global”而不是“ Inner!”的原因。 我们实际上并没有更改window.myVar的值。 相反,我们将其放在一旁,并在myInnerFunction内部创建一个名为myVar的新变量,然后修改该变量。
还要注意,当声明一个函数时,也就是在声明它的参数。 所以在这一行:
function myInnerFunction(myVar) {
您实际上是在声明一个名为myVar的变量,并将其附加到myInnerFunction的上下文中。
您不是在隐式地使用在myOuterFunction或全局myVar中声明的myVar变量的值。
它将产生与您执行此操作相同的结果:
function myInnerFunction(someOtherVar) {
结论
因此,您现在知道了JavaScript中变量作用域的基础知识(和中间体)。 JavaScript变量[以及函数,类和对象]可以具有四个[技术上三个]不同的作用域之一,具体取决于如何(在何种情况下)声明它们:
- 窗口(或“全局”)范围-声明后,可用于窗口中任何位置的任何脚本。
- 函数范围-仅适用于定义变量的函数和函数内部的对象。
- 类范围-仅适用于定义变量的类内部的函数和对象。
- 块作用域-仅适用于使用let语句创建的块内的函数和对象。
总结了今天有关可变范围的课程。 万岁,编写繁荣的代码!
From: https://bytes.com/topic/javascript/insights/655478-variable-scope-javascript