javascript中变量的范围是什么?它们在函数内部的作用域与在函数外部的作用域相同吗?或者这有关系吗?此外,如果变量是全局定义的,那么变量存储在哪里?
当前回答
运行代码。希望这能提供一个关于范围界定的想法
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);
其他回答
全局声明的变量具有全局范围。在函数中声明的变量的作用域是该函数,并隐藏同名的全局变量。
(我相信真正的JavaScript程序员可以在其他答案中指出许多微妙之处。特别是我在这个页面上看到了这到底意味着什么。不过,希望这个更为介绍性的链接足以让你开始。)
ES5及更早版本:
Javascript中的变量最初(在ES6之前)是函数范围的。词汇范围这一术语意味着您可以通过“查看”代码来查看变量的范围。
用var关键字声明的每个变量都在函数的作用域内。但是,如果在该函数中声明了其他函数,则这些函数将可以访问外部函数的变量。这称为作用域链。其工作方式如下:
当一个函数试图解析一个变量值时,它首先查看自己的范围。这是函数体,即花括号{}之间的所有内容(除了在此范围内的其他函数内的变量)。如果它在函数体中找不到变量,它将爬上链,查看函数中定义函数的变量范围。这就是词法作用域的含义,我们可以在代码中看到这个函数的定义,因此可以通过查看代码来确定作用域链。
例子:
//全局范围var foo=“全局”;var bar=“全局”;var foobar=“全局”;函数outerFunc(){//outerFunc范围var foo='outerFunc';var foobar='outerFunc';innerFunc();函数innerFunc(){//innerFunc范围var foo='innerFunc';console.log(foo);console.log(bar);console.log(foobar);}}outerFunc();
当我们试图将变量foo、bar和foobar记录到控制台时,会发生以下情况:
我们尝试将foo记录到控制台,foo可以在函数innerFunc本身中找到。因此,foo的值被解析为字符串innerFunc。我们试图将bar记录到控制台,但在函数innerFunc本身中找不到bar。因此,我们需要攀登范围链。我们首先查看定义了函数innerFunc的外部函数。这是outerFunc函数。在outerFunc的作用域中,我们可以找到变量栏,其中包含字符串“outerFun”。在innerFunc中找不到foobar。因此,我们需要将作用域链升级到innerFunc作用域。在这里也找不到它,我们爬到了另一个层次的全局范围(即最外面的范围)。我们在这里找到了保存字符串“global”的变量foobar。如果在攀爬范围链之后没有找到变量,JS引擎将抛出referenceError。
ES6(ES 2015)及以上版本:
词汇范围和范围的概念仍然适用于ES6。然而,引入了一种声明变量的新方法。具体如下:
let:创建块范围变量const:创建一个必须初始化且不能重新分配的块范围变量
var和let/cont之间最大的区别是var是函数范围的,而let/cont是块范围的。下面是一个例子来说明这一点:
let letVar=“全局”;var varVar=“全局”;函数foo(){if(真){//用let声明的这个变量的作用域是if块,块作用域设letVar=5;//用let声明的这个变量的作用域是函数块,函数作用域var varVar=10;}console.log(letVar);console.log(varVar);}foo();
在上面的示例中,letVar记录全局值,因为用let声明的变量是块范围的。它们不再存在于各自的块之外,因此无法在if块之外访问变量。
在EcmaScript5中,主要有两个作用域,局部作用域和全局作用域,但在EcmaScript6中,我们主要有三个作用域:局部作用域、全局作用域和一个称为块作用域的新作用域。
块范围示例如下:-
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.
}
试试这个奇怪的例子。在下面的示例中,如果a是一个初始化为0的数字,您将看到0,然后是1。除了a是一个对象,javascript将向f1传递a的指针,而不是它的副本。结果是两次都得到相同的警报。
var a = new Date();
function f1(b)
{
b.setDate(b.getDate()+1);
alert(b.getDate());
}
f1(a);
alert(a.getDate());
运行代码。希望这能提供一个关于范围界定的想法
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);
推荐文章
- Babel 6改变了它导出默认值的方式
- 如何配置历史记录?
- ES6模板文字可以在运行时被替换(或重用)吗?
- [Vue警告]:找不到元素
- 可以在setInterval()内部调用clearInterval()吗?
- AngularJS控制器的生命周期是什么?
- 无法读取未定义的属性“msie”- jQuery工具
- 我的蛋蛋怎么不见了?
- JavaScript中的排列?
- JavaScript中有睡眠/暂停/等待功能吗?
- 如何禁用文本选择使用jQuery?
- 如何停止事件冒泡复选框点击
- 如何在PHP中截断字符串最接近于一定数量的字符?
- 向对象数组添加属性
- 如何在Redux应用程序中动态加载代码分割的减速器?