JavaScript中变量的范围是什么?
javascript中变量的范围是什么?它们在函数内部和外部的作用域是否相同?或者这有什么关系?另外,如果变量是全局定义的,那么它们存储在哪里?全局声明的变量具有全局范围。在函数中声明的变量的作用域为该函数,并隐藏同名的全局变量JavaScript中变量的范围是什么?,javascript,function,variables,scope,var,Javascript,Function,Variables,Scope,Var,javascript中变量的范围是什么?它们在函数内部和外部的作用域是否相同?或者这有什么关系?另外,如果变量是全局定义的,那么它们存储在哪里?全局声明的变量具有全局范围。在函数中声明的变量的作用域为该函数,并隐藏同名的全局变量 (我相信真正的JavaScript程序员在其他答案中会指出许多微妙之处。特别是我在任何时候都会了解到这个的确切含义。希望这足以让您开始学习。)JavaScript使用作用域链来建立给定函数的作用域。通常有一个全局作用域,每个定义的函数都有自己的嵌套作用域。在另一个函数中
(我相信真正的JavaScript程序员在其他答案中会指出许多微妙之处。特别是我在任何时候都会了解到
这个的确切含义。希望这足以让您开始学习。)JavaScript使用作用域链来建立给定函数的作用域。通常有一个全局作用域,每个定义的函数都有自己的嵌套作用域。在另一个函数中定义的任何函数都有一个与外部函数链接的局部作用域。定义范围的始终是源中的位置
范围链中的元素基本上是一个映射,带有指向其父范围的指针
解析变量时,javascript从最里面的范围开始向外搜索。下面是一个示例:
<script>
var globalVariable = 7; //==window.globalVariable
function aGlobal( param ) { //==window.aGlobal();
//param is only accessible in this function
var scopedToFunction = {
//can't be accessed outside of this function
nested : 3 //accessible by: scopedToFunction.nested
};
anotherGlobal = {
//global because there's no `var`
};
}
</script>
var全局变量=7//==窗口全局变量
函数aGlobal(param){/==window.aGlobal();
//参数仅在此函数中可访问
变量scopedToFunction={
//无法在此功能之外访问
嵌套:3//可由以下人员访问:scopedToFunction.nested
};
另一个全局={
//全局的,因为没有变量`
};
}
您将需要研究闭包,以及如何使用闭包来创建闭包。TLDR
JavaScript具有词汇(也称为静态)作用域和闭包。这意味着您可以通过查看源代码来判断标识符的范围
这四个范围是:
全球-一切可见
函数-在函数(及其子函数和块)中可见
块-在块(及其子块)内可见
模块-在模块内可见
在全局范围和模块范围的特殊情况之外,使用var
(函数范围)、let
(块范围)和const
(块范围)声明变量。大多数其他形式的标识符声明在严格模式下具有块作用域
概述
作用域是标识符有效的代码基区域
词法环境是标识符名称和与其关联的值之间的映射
作用域由词汇环境的链接嵌套构成,嵌套中的每一级对应于祖先执行上下文的词汇环境
这些链接的词汇环境形成一个范围“链”。标识符解析是沿着此链搜索匹配标识符的过程
标识符解析仅在一个方向上发生:向外。这样,外部词汇环境就无法“看到”内部词汇环境
有三个相关因素决定JavaScript中的
如何声明标识符
其中声明了标识符
无论你在家还是在家
可以声明标识符的一些方法:
var
,let
和const
功能参数
捕捉块参数
函数声明
命名函数表达式
全局对象上隐式定义的属性(即,在非严格模式下缺少var
)
import
语句
eval
可以声明某些位置标识符:
全球环境
功能体
普通块
控制结构的顶部(例如,回路、if、while等)
控制结构体
模块
声明样式
变量
使用var
声明的标识符具有函数作用域,除了直接在全局上下文中声明之外,在这种情况下,它们作为全局对象上的属性添加并具有全局作用域。它们在eval
函数中的使用有单独的规则
让我们继续
使用声明的标识符让
和const
具有块作用域,除非它们直接在全局上下文中声明,在这种情况下它们具有全局作用域
注:let
、const
和var
。这意味着它们定义的逻辑位置是其封闭范围(块或函数)的顶部。但是,在控件通过源代码中的声明点之前,无法读取或分配使用let
和const
声明的变量。过渡期称为暂时死区
函数f(){
函数g(){
console.log(x)
}
设x=1
g()
}
f()//1,因为即使用'let'声明,x也被提升代码>在“Javascript 1.7”(Mozilla对Javascript的扩展)中,还可以通过以下方式声明块作用域变量:
据我所知,关键在于Javascript具有函数级别的作用域,而不是更常见的C块作用域
我发现许多JavaScript新手在理解继承在语言中默认是可用的以及函数作用域是目前为止唯一的作用域时遇到了困难。我提供了我在去年年底写的一个名为JSPretty的美化工具的扩展。功能为代码中的函数范围着色,并始终将颜色与该范围中声明的所有变量相关联。当在不同的范围内使用一个颜色来自一个范围的变量时,可以直观地演示闭包
请尝试以下功能:
请参见以下网址的演示:
查看以下网址的代码:
目前,该功能提供对dep的支持
var a = 4;
let (a = 3) {
alert(a); // 3
}
alert(a); // 4
var a = new Date();
function f1(b)
{
b.setDate(b.getDate()+1);
alert(b.getDate());
}
f1(a);
alert(a.getDate());
//chrome (v8)
var a = { 'test1':'test1val' }
test1 // error not defined
with (a) { var test1 = 'replaced' }
test1 // undefined
a // a.test1 = 'replaced'
//global variable
var a = 2;
//global function
function b(){
console.log(a); //access global variable
}
function b(){
var d = 21; //local variable
console.log(d);
function dog(){ console.log(a); }
dog(); //execute local function
}
console.log(d); //ReferenceError: dddddd is not defined
a = "global";
function outer(){
b = "local";
console.log(a+b); //"globallocal"
}
outer();
Name = 'global data';
document.Name = 'current document data';
(function(window,document){
var Name = 'local data';
var myObj = {
Name: 'object data',
f: function(){
alert(this.Name);
}
};
myObj.newFun = function(){
alert(this.Name);
}
function testFun(){
alert("Window Scope : " + window.Name +
"\nLocal Scope : " + Name +
"\nObject Scope : " + this.Name +
"\nCurrent document Scope : " + document.Name
);
}
testFun.call(myObj);
})(window,document);
var global_variable = "global_variable";
var hoisting_variable = "global_hoist";
// Global variables printed
console.log("global_scope: - global_variable: " + global_variable);
console.log("global_scope: - hoisting_variable: " + hoisting_variable);
if (true) {
// The variable block will be global, on true condition.
var block = "block";
}
console.log("global_scope: - block: " + block);
function local_function() {
var local_variable = "local_variable";
console.log("local_scope: - local_variable: " + local_variable);
console.log("local_scope: - global_variable: " + global_variable);
console.log("local_scope: - block: " + block);
// The hoisting_variable is undefined at the moment.
console.log("local_scope: - hoisting_variable: " + hoisting_variable);
var hoisting_variable = "local_hoist";
// The hoisting_variable is now set as a local one.
console.log("local_scope: - hoisting_variable: " + hoisting_variable);
}
local_function();
// No variable in a separate function is visible into the global scope.
console.log("global_scope: - local_variable: " + local_variable);
var carName = " BMW";
// code here can use carName
function myFunction() {
// code here can use carName
}
// code here can not use carName
function myFunction() {
var carName = "BMW";
// code here can use carName
}
var i = 10, v = 10;
for (var i = 0; i < 5; i++) { var v = 5; }
console.log(i, v);
// output 5 5
var i = 10, v = 10;
$.each([0, 1, 2, 3, 4], function(i) { var v = 5; });
console.log(i,v);
// output 10 10
var i = 1;
function abc() {
i = 2;
var i = 3;
}
console.log(i); // outputs 1
var i = 1;
function abc() {
var i; // var declaration moved to the top of the scope
i = 2;
i = 3; // the assignment stays where it is
}
console.log(i);
var myVariable = "Some text";
let myVariable = "Some text";
// i IS NOT known here
// j IS NOT known here
// k IS known here, but undefined
// l IS NOT known here
function loop(arr) {
// i IS known here, but undefined
// j IS NOT known here
// k IS known here, but has a value only the second time loop is called
// l IS NOT known here
for( var i = 0; i < arr.length; i++ ) {
// i IS known here, and has a value
// j IS NOT known here
// k IS known here, but has a value only the second time loop is called
// l IS NOT known here
};
// i IS known here, and has a value
// j IS NOT known here
// k IS known here, but has a value only the second time loop is called
// l IS NOT known here
for( let j = 0; j < arr.length; j++ ) {
// i IS known here, and has a value
// j IS known here, and has a value
// k IS known here, but has a value only the second time loop is called
// l IS NOT known here
};
// i IS known here, and has a value
// j IS NOT known here
// k IS known here, but has a value only the second time loop is called
// l IS NOT known here
}
loop([1,2,3,4]);
for( var k = 0; k < arr.length; k++ ) {
// i IS NOT known here
// j IS NOT known here
// k IS known here, and has a value
// l IS NOT known here
};
for( let l = 0; l < arr.length; l++ ) {
// i IS NOT known here
// j IS NOT known here
// k IS known here, and has a value
// l IS known here, and has a value
};
loop([1,2,3,4]);
// i IS NOT known here
// j IS NOT known here
// k IS known here, and has a value
// l IS NOT known here
function myFunction() {
var carName = "Volvo";
alert(carName);
// code here can use carName
}
class {
var carName = " Volvo";
// code here can use carName
function myFunction() {
alert(carName);
// code here can use carName
}
}
for ( let i = 0; i < 10; i++)
{
statement1...
statement2...// inside this scope we can access the value of i, if we want to access the value of i outside for loop it will give undefined.
}
var x = 10
let y = 10
const z = 10
{
x = 20
let y = 20
const z = 20
{
x = 30
// x is in the global scope because of the 'var' keyword
let y = 30
// y is in the local scope because of the 'let' keyword
const z = 30
// z is in the local scope because of the 'const' keyword
console.log(x) // 30
console.log(y) // 30
console.log(z) // 30
}
console.log(x) // 30
console.log(y) // 20
console.log(z) // 20
}
console.log(x) // 30
console.log(y) // 10
console.log(z) // 10