-
执行上下文
在代码开始执行之前,会将其中某些语句的位置提前,使其优先执行。
范围是一段 <script> 内(全局)或者一个函数内。其中,提前的有:全局中:变量定义(var)、函数声明(function XX)
函数中:变量的定义、函数声明、this、arguments(传入属性)console.log (a); //undefined 只是underfined而不是报错。 var a = 100; // 因为执行上下文,var a 已经提前,已经定义了a,但是还没有执行负值。 fn ('AAA'); // 'AAA' 20 , 函数声明已提前运行,所以可以使用该方法。 function fn(name) { age = 20; // 在这个函数内,var age 也是已经提前了。所以可以赋值。 console.log (name, 20); var age; }
-
this
this 要在执行时才能确认它的值,定义时无法确认。
var a = { name: 'AAA'; fn: function () { console.log (this.name); // 就是这个this }; }; // a 引用一个对象,该对象有name属性为 'A',有个fn属性为一个函数。 // 下面是运行 a.fn(); // AAA // 用a去执行它自身属性的函数时,this传进去的就是它自身。 a.fn.call ({name:"BBB"}); // BBB // 把 a.fn 这个函数的方法去给{name:"BBB"}这个对象使用, // 相当于把 a 替换成 {name:"BBB"} 去执行fn函数。 var fn1 = a.fn(); fn1(); // window 这个函数就是由window来运行的。
作为构造函数执行时、作为对象属性执行时、作为普通函数执行时
在使用call、apply、bind方法时,this 是会改变的。
-
作用域
只有全局作用域(script标签)和函数作用域,
没有块级作用域(在Java中把 { } 之间作为一个块)。var a = 100; function fn () { var a = 200; console.log ("fn", a); } console.log ("global", a); // "global" 100 fn(); // "fn" 200 // 这个例子中,有两个作用域,一个是全局,一个是 fn 函数, // 这两个作用域中都各自定义了 a 的值。所以在他们各自的作用域中打印a,就会由两个互不影响的值。
-
作用域链
当前作用域没有定义的变量,叫做自由变量。
在 F2 这个作用域里,没有定义 a 和 b ,所以他们是自由变量,var a = 100; function F1 () { var b = 200; function F2 () { var c = 300; console.log (a); // 100 console.log (b); // 200 console.log (c); // 300 }; F2(); }; F1();
但是会去 F2 的父级作用域中去寻找,找到了 b ,
但还是没有 a ,继续向上找,知道在全局作用域找到并打印。
-
-
闭包
在Javasrcipt中,闭包就是变量解析的过程,
正常情况下,作用域外(父作用域)无法直接获取到作用域内(子作用域)的变量,
但在本作用域内,创建一个新函数,并返回到父作用域中,通过作用域链,
就可以在父作用域中,通过这个新函数获取到子作用域内的变量。
而这个新函数,就是一个闭包(卧底?内应?)。function F1 () { var a = 100; // 返回一个函数 return function () { console.log (a); }; }; var f1 = F1 (); // F1 运行后,得到一个函数,并赋值给f1。 var a = 200; f1(); // 100 // 以上中,return 的 function 就是一个闭包,传到外面 // 同时,在该函数作用域中,没定义 a 变量, // 所以在运行时,就到该作用域的父作用域中找,即 F1 作用域。
-
闭包的使用场景
函数作为返回值(就是上面这种)或作为参数传递的时候。
闭包的概念解释起来比较难懂,记住用法就好。
-
- 这里有阮一峰的——学习Javascript闭包(Closure)
- 还有知乎的回答——如何才能通俗易懂的解释javascript里面的‘闭包’?
Wait me back