作用域的整理
作用域
全局作用域
1、直接写在js的代码中,都在全局作用域
2、全局作用域在页面打开时创建,在页面关闭时销毁。
3、在全局作用域中有一个全局对象window,它代表的是一个浏览器的窗口,它由我们的浏览器创建,我们可以直接使用。
4、在全局作用域中定义的都是全局变量,在页面的任何位置都可以调用。
console.log(window);
结果:Object window
4、在全局作用域中
1、创建的对象都会作为window对象的属性保存
var a = 10;
console.log(window.a); //window的属性a
console.log(a); //变量a
结果都为10,所以在全局作用域中,创建的对象都会被作为window对象的属性保存
当没有声明变量c时,输出的结果有差异
console.log(window.c); //结果为undefined
console.log(c); //报错
输出对象的空属性会显示undefined,而直接输出一个空的变量会报错
2、创建的函数都会作为window对象的方法保存。
function fun() {
console.log("我是window对象的方法")
}
fun();
window.fun();
输出的结果一样,因为函数fun()就是window对象的方法。
5、变量的声明提前 函数的声明提前
变量的声明提前:
1、使用var关键字声明变量,变量会在所有代码被执行之前声明。(不会赋值,只会在变量赋值的这一行赋值)
2、如果不使用var关键字声明,变量的声明则不会提前声明,如果调用在方法之后声明的非var变量,则会出现报错。(不使用var声明的变量为全局变量)
1、变量的声明提前
var a = 10;
console.log(a);结果 10
console.log(b); 结果 undefined
var b = 5;
问题:b为什么是undefined,而不是报错呢?(而24行报错了)
原因:var声明的变量,变量的声明会提前,变量的初始化还在原位置
原因:
console.log(b); 结果 undefined
var b = 5;
就相当于
var b;
console.log(b);
b=5
而
console.log(c);
c=5 结果为:报错
。。。。。。。。。。。。。
console.log(c);
let c = 5; 结果为:报错
函数的声明提前:
1、使用函数声明function 函数名(){}
2、使用函数表达式创建的函数不能函数声明提前
2、函数的声明提前
例一:正常
var a = function() {
console.log("我是函数A");
}
function fun() {
console.log("我是函数fun");
}
a(); 结果 我是函数A
fun();结果 我是函数fun
例二:异常
fun();结果 我是函数fun
a(); 结果 报错 原因:console.log(a) undefined
undefined 怎么会有函数呢? 所以只是变量声明的提升
var a = function() {
console.log("我是函数A");
}
function fun() {
console.log("我是函数fun");
}
函数作用域
1、调用函数时创建的作用域,函数执行以后,作用域销毁。
2、每调用一次函数就会创建一个新的函数作用域,他们之间是相互独立的。
3、在函数作用域中,可以访问到全局变量
4、在全局作用域中,无法访问到局部。(若要访问,需要牵扯到闭包)
5、当函数作用域中操作一个函数,则会先使用,若没有,则去上一级寻找。
6、在函数作用域中,同样也有函数声明。
函数内部的变量只能在函数内部使用
var a = 10;
function fun(){
var b =20;
console.log(a); 结果10
console.log(b); 结果20
}
fun();
console.log(b); 结果 报错
就近原则
var a = 10;
fun();
function fun() {
var a = 20;
console.log(a); 结果20
}
console.log(a); 结果时10
当函数内部没有要输出的变量是,会返回上一级寻找
var a = 10;
function fun() {
console.log(a); 结果 10
}
fun();
注意: 此时为underfined
样式一
var a = 10;
function fun() {
console.log(a);结果 underfined 就近原则
var a = 10;
}
fun();
样式二
var a = 20;
function fun() {
console.log(a); //结果为20
注意:a = 10;
注意:console.log(a); //结果为10 就近原则
}
fun();
样式一和样式二不一样的原因 样式一方法中的a为局部变量,样式二方法中的a为全局变量
在含有参数的方法中使用参数遇到的问题
var e = 1200;
funOne();
funTwo();
function funOne() {
console.log(e); 结果1200
}
function funTwo(e) {
console.log(e); 结果underfined
}
结果的原因
funTwo()含有一个参数e,就相当于声明的一个参数e
相当于 function funTwo(e) {
var e;
console.log(e); 结果underfined
}
闭包
用途:
1、解决函数外部无法访问到函数内部变量的问题。
// 全局作用域
function fun() {
// 函数作用域
var a = 10;
}
fun()
console.log(a);//报错
原因:函数作用域中的变量不能被函数外部直接访问
解决方案:使用return,使这个方法返回。
//全局作用域
function fun() {
//函数作用域
var a = 10;
return a;
}
fun()
console.log(fun());10
//或者
var name = fun();
console.log(name);10
2、通过闭包可以让函数中的变量持久保持
function aer() {
for (var a = 0; a < 7; a++) {
b[a].addEventLitener("click", function() {
console.log(a);
函数遍历七次 七次输出的结果都是a
})
}
}
原因:for循环只是给b绑定事件,但是里面的函数代码并不会执行。如果点击,此时a已经是7了
闭包的使用方法汇总
1、使用全局变量
function(){
var a =10;
b=a;
}
console.log(b); 结果:10
原因:b没有用var声明,所以b是全局变量,在任何地方都可以使用。