@GivenCui
        
        2016-05-25T11:13:30.000000Z
        字数 3356
        阅读 920
    js高级
作用域 : 变量和函数的访问范围, 作用域可以控制变量和函数的可见性和生命周期.
- 全局作用域
 - 局部作用域
 
<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><title>全局作用域与局部作用域</title><script type = "text/javascript">/*全局作用域*/// 全局变量在全局作用域中,也就是说,在任何位置都可以访问到这个全局变量var globalName = "这是全局变量" ;// 在全局作用域中访问console.log("全局作用局访问: " + globalName);// 在普通的函数中访问function fn () {console.log("在普通的函数中访问: "+ globalName);}fn();// 在构造函数中访问function Person () {this.name = globalName;}var person = new Person();console.log("在构造函数中访问: " + person.name);// 在字面量对象中访问var obj = {name : globalName}console.log("在字面量对象中访问: " + obj.name);/** 局部作用域*/function fn2() {var partName = "这是局部变量";// 局部变量在当前作用域下一定可以访问到console.log(partName);function subFn() {console.log("某个函数的子函数(内部函数),也可以访问到当前函数的局部变量" + partName);}subFn();}fn2();// try catch语句: 用来捕捉异常,如果报错程序会停止运行,但是用try catch捕捉的话就算出现异常,程序照样会执行.// 使用场景 : 有报错风险的地方使用try{// 有报错风险的代码console.log(partName); // 报错} catch (exception) { // catch中的参数叫什么都行// 捕捉异常后,打印异常信息console.log(exception.toString());}console.log("程序能正常运行");</script></head><body></body></html>
- 1.在JS中没有块级的概念. 其它语言中“{}”中的都是局部变量,但在JS中,只有函数的作用域内的才是局部变量,例如 for(){} if(){}else{}等中的“ {} ”在JS中不是块级.
 - 2.在JS中, 如果没有用var去声明变量的话, 那么这个变量就是全局变量
 
<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><title>作用域的注意事项</title><script type = "text/javascript">// 1、在JS中是没有块级概念的function fn () {for (var i = 0; i < 4 ; i++) {}// 在JS中可以访问到console.log(i);}fn();// 2. 不用var的变量是全局变量function fn2 () {name = "abc";}fn2();// 可以访问到不用var声明的变量console.log(name);</script></head><body></body></html>
<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><title>混合练习</title><script type = "text/javascript">var a = "a"; // 全局变量function fn3 (d) {b = "b"; // 全局变量 (没var)var c = "c"; // fn3的局部变量function subFn() {var e = d; // subFn()的局部变量if (true) {var f = "f"; // subFn()的局部变量}}subFn();}fn3();</script></head><body></body></html>
作用域链 : 访问某个变量,先去当前的作用域去查找这个变量,如果查找不到,就沿着作用域链(该作用域的父级作用域去找), 以此类推,直到找到头为止,最顶端是window对象,全局作用域. 如果找不到,就会报错.
<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><title>作用域链</title><script type = "text/javascript">// 作用域链var name = "abc";function fn () {var name = "abc";function subFn1 () {var name = "bcd";console.log("name"); // bcd}function subFn2 () {console.log(name); // abc}/*原理是:1. 预解析2. 逐条指行*/// subFn1() --> fn --> window(作用域链的最顶端)subFn1();subFn2();}fn()</script></head><body></body></html>
<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><title>for循环中套函数陷阱</title><script type = "text/javascript">// 经典面试题function initBtnEvent () {for (var i =1; i < 4; i++) {var tempBtn = document.getElementById("button" + i);tempBtn.addEventListener("click", function () {alert("button " + i);});}}window.onload = initBtnEvent;</script></head><body><input type = "button" value = "Button1" id ="button1" /><input type = "button" value = "Button2" id ="button2" /><input type = "button" value = "Button3" id ="button3" /></body></html>
JS中this关键字的指向是动态的,动态有好处也有坏处,有的时候会出现一些意想不到的结果,那么我们可以通过call和apply等方法对this关键字进行固定。
1、call方法:可以指定函数内部的this指向,并且进行该函数。
2、apply :和call方法功能一样,只不过参数为数组。
<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><title>固定this的方法</title><script type = "text/javascript">// 1. call方法var name = "abc,this访问的是全局";var obj = {name : "bcd,通过call让this指向了obj"};function fn () {console.log(this.name);}fn();// 通过函数调用call方法, 可以改变this的指向, 并且在参数所在的环境中运行.fn.call(obj);// 待参数的function fn2 (a, b) {console.log(a + b);}// 在全局环境中运行fn2.call(this,5,8); // 13// apply方法和call功能一样, 就是参数换成了数组fn2.apply(this, [6, 9]); // 15</script></head><body></body></html>