标签:函数 obj 运行 -- 如何 back col 声明 预测
作用域是根据名称查找变量的一套规则,javascript的作用域为词法作用域,词法作用域是由你在写代码时将变量和块作用域写在哪里来决定的,词法分析阶段基本能够知道全部标识符在哪里以及是如何声明的,从而能够预测在执行过程中如何对它们进行查找。词法作用域的特征就是作用域的定义发生在代码的书写阶段。
作用域链:
当一个块或函数嵌套在另一个块或函数中时,就发生了作用域的嵌套,因此,在当前作用域中无法找到某个变量时,引擎就会在外层嵌套的作用域中继续查找,直到找到该变量, 或抵达最外层的作用域(也就是全局作用域)为止。如果将作用域比作气泡,那么每声明一个函数或创建一个块都会为其自身创建一个气泡,气泡的外部无法访问到气泡内部的变量,但是里层的气泡能够顺着作用域链向外访问外层的变量。
由于气泡的外部无法访问到气泡内部的变量的机制,所以可以使用函数将变量包装起来达到隐藏变量的功能,匿名立即执行函数就非常合适。
var a = 1 (function() { var a = 2 console.log(a) // 2 })() console.log(a) // 1
以 (function 而不是 function 开头是非常重要的区别,函数会被当作函数表达式而不是一个标准的函数声明来处理。
除了函数,使用with和catch语句也会生成代码块,let 关键字可以将变量绑定到所在的任意作用域中(通常是 { .. } 内部)。换句话说,let 为其声明的变量隐式地了所在的块作用域。
在javascript中this的机制则更类似于动态作用域,而动态作用域并不关心函数和作用域是如何声明以及在何处声明的,只关心它们从何处调用。换句话说,动态作用域链是基于调用栈的,而不是代码中的作用域嵌套。this的绑定和函数声明的位置没有任何关系,只取决于函数的调用方式。
this 既不指向函数自身也不指向函数的词法作用域,this 实际上是在函数被调用时发生的绑定,它指向什么完全取决于函数在哪里被调用。
当一个函数被调用时,会创建一个活动记录(有时候也称为执行上下文)。这个记录会包含函数在哪里被调用(调用栈)、函数的调用方法、传入的参数等信息。this 就是记录的其中一个属性,会在函数执行的过程中用到。
要想知道this的指向,就要弄清楚函数的调用位置。
function baz() { // 当前调用栈是:baz // 因此,当前调用位置是全局作用域 console.log( "baz" ); bar(); // <-- bar 的调用位置 } function bar() { // 当前调用栈是 baz -> bar // 因此,当前调用位置在 baz 中 console.log( "bar" ); foo(); // <-- foo 的调用位置 } function foo() { // 当前调用栈是 baz -> bar -> foo // 因此,当前调用位置在 bar 中 console.log( "foo" ); } baz(); // <-- baz 的调用位置
2.1 判断this
1. 函数是否在 new 中调用(new 绑定)?如果是的话 this 绑定的是新创建的对象。
var bar = new foo()
2. 函数是否通过 call、apply(显式绑定)或者硬绑定调用?如果是的话,this 绑定的是 指定的对象。
var bar = foo.call(obj2)
3. 函数是否在某个上下文对象中调用(隐式绑定)?如果是的话,this 绑定的是那个上下文对象。
var bar = obj1.foo()
4. 如果都不是的话,使用默认绑定。如果在严格模式下,就绑定到 undefined,否则绑定到全局对象。
var bar = foo()
5. 箭头函数执行时没有自己的this,箭头函数中的this为函数运行时所在上下文的this
标签:函数 obj 运行 -- 如何 back col 声明 预测
原文地址:https://www.cnblogs.com/zsp-cool/p/14480118.html