全局作用域和局部作用域
全局作用域在任何地方都能被访问:
例如name1 在方法changeName() 里面和外面都可以打印出来
var name1="haha";
function changName(){
var name2="xixi";
console.log(name1); // haha
console.log(name2);// xixi
}
changName();
console.log(name1);//haha
console.log(name2);//Uncaught ReferenceError: name2 is not defined
局部作用域一般只在自己的局部区域被访问,在changeName()外面访问 name2 的时候报错,只能在期函数(方法)里面被访问。
作用域链
作用域链决定了全局作用域和局部作用域的变量访问权限。
1、每次进入一个新的执行环境,都会创建一个用于搜索变量和函数的作用域链。
2、作用域链是函数被创建的作用域中对象的集合。
3、作用域链可以保证对执行环境有权访问的所有变量和函数的有序访问。
4、沿着作用域一级一级的向上搜索。搜索过程始终是从作用域的前端逐地向后回溯,直到找到(变量、函数)(找不到,就会导致错误发生)。
var name1 = "haha";
function changeName() {
var name2 = "xixi";
function swapName() {
console.log(name1); //haha
console.log(name2); //xixi
var tempName = name2;
name2 = name1;
name1 = tempName;
console.log(name1); //xixi
console.log(name2); //haha
console.log(tempName); //xixi
}
swapName();
console.log(name1); //haha
console.log(name2); //xixi
//console.log(tempName);抛出错误:Uncaught ReferenceError: tempName is not defined
}
changName();
console.log(name1);
//console.log(name2); 抛出错误:Uncaught ReferenceError: name2 is not defined
//console.log(tempName);抛出错误:Uncaught ReferenceError: tempName is not defined
上述代码中,一共有三个执行环境:全局环境、changeName()的局部环境和 swapName() 的局部环境。所以,
1.函数 swapName()的作用域链包含三个对象:自己的变量对象----->changeName()局部环境的变量对象 ----->全局环境的变量对象。
2.函数changeName()的作用域包含两个对象:自己的变量对象----->全局环境的变量对象。
就上述程序中出现的变量和函数来讲(不考虑隐形变量):
1.swapName() 局部环境的变量对象中存放变量 tempName;
2.changeName() 局部环境的变量对象中存放变量 name2 和 函数swapName();
3.全局环境的变量对象中存放变量 name1 、函数changeName();
作用域链相关知识的总结:
1.执行环境决定了变量的生命周期
2.执行环境有全局执行环境(全局环境)和局部执行环境之分。
3.每次进入一个新的执行环境,都会创建一个用于搜索变量和函数的作用域链
4.函数的局部环境可以访问函数作用域中的变量和函数,也可以访问其父环境,乃至全局环境中的变量和环境。
5.全局环境只能访问全局环境中定义的变量和函数,不能直接访问局部环境中的任何数据。
闭包
参考链接:https://www.ruanyifeng.com/blog/2009/08/learning_javascript_closures.html
1、闭包就是能够读取其他函数内部变量的函数,因为js语言没有php等后端语言那种类的私有属性概念,所以产生了闭包这种思想。闭包就是将函数内部和函数外部连接起来的一座桥梁。
2、闭包就是让这些变量的值始终保持在内存中(认为是私有属性)。
这就是闭包表现的形式
var add = (function () {
var counter = 0;
return function () {
return counter += 1;
}
})();
console.log(add());
console.log(add());
这是作用域指向的案例,在函数表达式getNameFunc中this指的object对象。
var name = "The Window";
var object = {
name : "My Object",
getNameFunc : function(){
var that = this;
return function(){
return that.name;
};
}
};
alert(object.getNameFunc()());
var name = "The Window";
var object = {
name: "My Object",
getNameFunc: function () {
console.log(this);
var that = this;
ff = test();
return ff;
//这是个孤立的函数,所以他的this指向的是全局window,至于怎么判断是孤立的,凭感觉吧。
function test() {
console.log(this);
return that.name;
};
},
};
console.log(object.getNameFunc());