就是变量声明的区域,就是变量和函数的可访问范围javascript
在全局做用域中声明的变量叫作全局变量,全局做用域的变量能够在js中任何地方调用 ,变量没有在函数内声明或者声明的时候没有带var就是全局变量,拥有全局做用域。特殊:var a = b = c = 0; b与c是全局变量。
java
如,在函数内部声明的变量只能在函数内部访问es6
在javascript中,函数里面定义的变量,能够在函数里面被访问,但在函数外没法访问。而由花括号封闭的代码块都有本身的做用域,于是支持根据条件来定义变量,变量在执行完毕后会被销毁,注意在es6以前的版本,并无块级做用域,只有函数做用域和全局做用域
,for循环的循环体中是函数做用域,for循环内部定义的变量在整个所在的函数内部是能够访问的。bash
举个栗子
函数
for(var i =0;i<10;i++){
//console.log(i)
}
console.log(i) //这里i打印为10,i的做用域是全局做用域
复制代码
var t = 9;
function f1() {
var t2 = 10;
console.log(t);
console.log(t3)
function f2() {
var t3 = 200;
console.log(t2);
return t2 * t2;
}
return f2()
}
f1();
复制代码
这样就造成了一个做用域链f2.Scope ===> f1.Scope ===> global.Scope
ui
函数在执行的时候会沿着最末端的做用域依次向上查找变量,所以,子域能够访问父域的变量,而父域不能够访问子域的
es5
上述代码的执行结果为spa
var t = 9;
function f1() {
var t2 = 10;
console.log(t);//9
console.log(t3)//父级不能够访问子级的变量。报错 not defined
function f2() {
var t3 = 200;
console.log(t2); //10
return t2 * t2;
}
return f2()
}
f1();
复制代码
若是一个声明的变量在函数体内,那么它的做用域就是函数内部。若是是在全局环境下声明的,那么它的做用域就是全局的。经过var声明的变量是没法用delete删除的。code
函数内部的声明的变量会被提高到函数的头部。函数在解析执行的时候,先进行变量声明处理,而后再运行函数内部的代码。ip
变量和赋值语句一块儿书写,在js引擎解析时,会将其拆成声明和赋值2部分,声明置顶,赋值保留在原来位置
function a(){
var b = 1
}
复制代码
上述代码就至关于
function a(){
var b
b = 1
}
复制代码
变量重复声明不会出错,后面的会覆盖前面的。
var a = 1
var a = 2
console.log(a)//被覆盖,a的值为2
复制代码
当函数名和变量名相同时, 函数 > 变量,也就是先函数提高,后变量提高
var a = 1
function a(){
}
console.log(a)//a打印1
复制代码
既然是先函数提高后变量提高那为何会打印变量的值呢,由于,重复声明是会被后面的覆盖的
上述代码至关于
var a = function(){
}
var a = 1
console.log(a)//a打印1
复制代码
咱们来看几个题目在巩固一下做用域和变量提高
if (!("a" in window)) {
var a = 1;
}
console.log(a);
复制代码
if (!("a" in window)) {
var a = 1;
}
console.log(a);//undefined
复制代码
1."a" in window是判断在全局做用域中存不存在a,若存在则为true,不存在为fasle
2.在es5中函数是没有块级做用域的,所以在if中定义的变量的做用域为包括此if语句的做用域,即变量a的做用域为全局做用域
3.在js执行过程当中会先进行变量提高,所以在全局中先声明一个变量a
4.if()的判断为false,所以不会a不会赋值
5打印a为undefined
var a
if (!("a" in window)) { // true
a = 1;
}
console.log(a);//undefined
复制代码
var a = 18;
function d() {
console.log(a);
var a = { age: 19};
console.log(a);
}
d(); // 输出?
console.log(a);
复制代码
var a = 18;
function d() {
console.log(a);//undefiend
var a = { age: 19};
console.log(a); //{ age: 19};
}
d(); // 输出?
console.log(a);//18
复制代码
在访问变量时会先在访问的做用域进行查找
1.函数d在执行的时候,遇到var a = {age:19}时进行了变量提高,只声明没有赋值,所以第一个打印语句打印undefined
2.全局中的a在全局中查找,打印18
//至关于
var a
a = 18;
function d() {
var a
console.log(a);//undefiend
a = { age: 19};
console.log(a); //{ age: 19};
}
d(); // 输出?
console.log(a);//18
复制代码
练习1
console.log(a);
var a = 20;
console.log(a);
function a() {
}
复制代码
练习2
f();
console.log(a);
console.log(b);
console.log(c);
function f() {
var a = b = c = 9;
console.log(a);
console.log(b);
console.log(c);
}
复制代码
练习3
f();
function f() {
for(var k = 0; k <10; k++) {
console.log(k);
}
console.log(k);
}
复制代码
console.log(a); //打印函数a
var a = 20;
console.log(a); //20
function a() {
}
复制代码
f();
console.log(a);//Uncaught ReferenceError: a is not defined
console.log(b);//若是代码能够执行到这里(忽略上述行的报错),打印9
console.log(c);//若是代码能够执行到这里(忽略上述行的报错),打印9
function f() {
var a = b = c = 9;
console.log(a);//9
console.log(b);//9
console.log(c);//9
}
复制代码