[关闭]
@GivenCui 2016-05-25T19:13:30.000000Z 字数 3356 阅读 810

重新认识作用域

js高级



目录



JS课程合集跳转链接


作用域的相关概念

作用域 : 变量和函数的访问范围, 作用域可以控制变量和函数的可见性和生命周期.


  • 全局作用域
  • 局部作用域
  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>全局作用域与局部作用域</title>
  6. <script type = "text/javascript">
  7. /*
  8. 全局作用域
  9. */
  10. // 全局变量在全局作用域中,也就是说,在任何位置都可以访问到这个全局变量
  11. var globalName = "这是全局变量" ;
  12. // 在全局作用域中访问
  13. console.log("全局作用局访问: " + globalName);
  14. // 在普通的函数中访问
  15. function fn () {
  16. console.log("在普通的函数中访问: "+ globalName);
  17. }
  18. fn();
  19. // 在构造函数中访问
  20. function Person () {
  21. this.name = globalName;
  22. }
  23. var person = new Person();
  24. console.log("在构造函数中访问: " + person.name);
  25. // 在字面量对象中访问
  26. var obj = {
  27. name : globalName
  28. }
  29. console.log("在字面量对象中访问: " + obj.name);
  30. /*
  31. * 局部作用域
  32. */
  33. function fn2() {
  34. var partName = "这是局部变量";
  35. // 局部变量在当前作用域下一定可以访问到
  36. console.log(partName);
  37. function subFn() {
  38. console.log("某个函数的子函数(内部函数),也可以访问到当前函数的局部变量" + partName);
  39. }
  40. subFn();
  41. }
  42. fn2();
  43. // try catch语句: 用来捕捉异常,如果报错程序会停止运行,但是用try catch捕捉的话就算出现异常,程序照样会执行.
  44. // 使用场景 : 有报错风险的地方使用
  45. try{
  46. // 有报错风险的代码
  47. console.log(partName); // 报错
  48. } catch (exception) { // catch中的参数叫什么都行
  49. // 捕捉异常后,打印异常信息
  50. console.log(exception.toString());
  51. }
  52. console.log("程序能正常运行");
  53. </script>
  54. </head>
  55. <body>
  56. </body>
  57. </html>

关于作用域需要注意的一些问题

  • 1.在JS中没有块级的概念. 其它语言中“{}”中的都是局部变量,但在JS中,只有函数的作用域内的才是局部变量,例如 for(){} if(){}else{}等中的“ {} ”在JS中不是块级.
  • 2.在JS中, 如果没有用var去声明变量的话, 那么这个变量就是全局变量
  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>作用域的注意事项</title>
  6. <script type = "text/javascript">
  7. // 1、在JS中是没有块级概念的
  8. function fn () {
  9. for (var i = 0; i < 4 ; i++) {
  10. }
  11. // 在JS中可以访问到
  12. console.log(i);
  13. }
  14. fn();
  15. // 2. 不用var的变量是全局变量
  16. function fn2 () {
  17. name = "abc";
  18. }
  19. fn2();
  20. // 可以访问到不用var声明的变量
  21. console.log(name);
  22. </script>
  23. </head>
  24. <body>
  25. </body>
  26. </html>

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>混合练习</title>
  6. <script type = "text/javascript">
  7. var a = "a"; // 全局变量
  8. function fn3 (d) {
  9. b = "b"; // 全局变量 (没var)
  10. var c = "c"; // fn3的局部变量
  11. function subFn() {
  12. var e = d; // subFn()的局部变量
  13. if (true) {
  14. var f = "f"; // subFn()的局部变量
  15. }
  16. }
  17. subFn();
  18. }
  19. fn3();
  20. </script>
  21. </head>
  22. <body>
  23. </body>
  24. </html>

作用域链

作用域链 : 访问某个变量,先去当前的作用域去查找这个变量,如果查找不到,就沿着作用域链(该作用域的父级作用域去找), 以此类推,直到找到头为止,最顶端是window对象,全局作用域. 如果找不到,就会报错.


  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>作用域链</title>
  6. <script type = "text/javascript">
  7. // 作用域链
  8. var name = "abc";
  9. function fn () {
  10. var name = "abc";
  11. function subFn1 () {
  12. var name = "bcd";
  13. console.log("name"); // bcd
  14. }
  15. function subFn2 () {
  16. console.log(name); // abc
  17. }
  18. /*
  19. 原理是:
  20. 1. 预解析
  21. 2. 逐条指行
  22. */
  23. // subFn1() --> fn --> window(作用域链的最顶端)
  24. subFn1();
  25. subFn2();
  26. }
  27. fn()
  28. </script>
  29. </head>
  30. <body>
  31. </body>
  32. </html>
  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>for循环中套函数陷阱</title>
  6. <script type = "text/javascript">
  7. // 经典面试题
  8. function initBtnEvent () {
  9. for (var i =1; i < 4; i++) {
  10. var tempBtn = document.getElementById("button" + i);
  11. tempBtn.addEventListener("click", function () {
  12. alert("button " + i);
  13. });
  14. }
  15. }
  16. window.onload = initBtnEvent;
  17. </script>
  18. </head>
  19. <body>
  20. <input type = "button" value = "Button1" id ="button1" />
  21. <input type = "button" value = "Button2" id ="button2" />
  22. <input type = "button" value = "Button3" id ="button3" />
  23. </body>
  24. </html>

补充 : 固定this的方法 (call 和 apply)

JS中this关键字的指向是动态的,动态有好处也有坏处,有的时候会出现一些意想不到的结果,那么我们可以通过call和apply等方法对this关键字进行固定。
1、call方法:可以指定函数内部的this指向,并且进行该函数。
2、apply :和call方法功能一样,只不过参数为数组。

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>固定this的方法</title>
  6. <script type = "text/javascript">
  7. // 1. call方法
  8. var name = "abc,this访问的是全局";
  9. var obj = {
  10. name : "bcd,通过call让this指向了obj"
  11. };
  12. function fn () {
  13. console.log(this.name);
  14. }
  15. fn();
  16. // 通过函数调用call方法, 可以改变this的指向, 并且在参数所在的环境中运行.
  17. fn.call(obj);
  18. // 待参数的
  19. function fn2 (a, b) {
  20. console.log(a + b);
  21. }
  22. // 在全局环境中运行
  23. fn2.call(this,5,8); // 13
  24. // apply方法和call功能一样, 就是参数换成了数组
  25. fn2.apply(this, [6, 9]); // 15
  26. </script>
  27. </head>
  28. <body>
  29. </body>
  30. </html>
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注