1.js中的执行上下文或者执行环境:execution context,简称EC;
2.
1 console.log(a);//undefined 2 var a=200; 3 fn('lili'); 4 function fn(name){ 5 age=23; 6 console.log(name,age);//lili 23 7 var age; 8 }
分析这段代码的执行过程:首先需要记得,
在js中,存在变量提升。函数声明和变量声明总是会被解释器悄悄地被“提升”到方法体的最顶端,因此一般在写代码的时候,通常我们在每个作用域开始前声明这些变量,这也是正常的 JavaScript 解析步骤,易于我们理解。
因此这段代码,就可以这样变形:
//函数提升优先于变量提升 function fn(name){ var age; age=23; console.log(name,age);//lili 23 } var a; console.log(a);//只声明变量a,但是并未赋值,因此为undefined var a=200; fn('lili');//函数在执行的过程中,传入参数name='lili',进入fn的执行域中,var age提前;并赋值为23
*增加:函数覆盖
1 var a; 2 function a(){} 3 console.log(a);//function a(){}
1)函数声明和变量声明均会被提升,但是函数声明会覆盖变量声明,就像上面的代码。
2)但是,如果变量已被赋值,则最终的值为变量的值:
1 var a=1; 2 function a(){} 3 console.log(a);//1
3)变量重复声明是无用的,但是函数的重复声明会覆盖前面的声明;
//变量的重复声明 var a = 1; var a; console.log(a);//1 //函数声明优于变量声明,故变量声明无作用 var a; function a(){ console.log(1);//1 } a(); //后面的函数声明会覆盖前面的函数声明 a();//44 function a(){ console.log(1); } function a(){ console.log(44); }
因此写代码的时候,应该避免在同一作用域内重复声明
3.再了解一下执行上下文的其他:
- 范围:一段<script>或者一个函数;
- 全局:变量定义、函数声明;
- 函数:变量定义、函数声明、this、arguments
定义函数有两种方式:函数声明以及函数表达式(函数声明的一个重要特征:函数声明提升)
小tip:区分函数声明以及函数表达式
1 //函数声明 2 function fn(){ 3 ... 4 } 5 6 //函数表达式 7 var fn = function(){ 8 ... 9 }
1.this:要在执行时才能确定值,定义时无法确定。
1 var a={ 2 name:'A', 3 fn:function(){ 4 console.log(this.name);//undefined 5 } 6 }; 7 8 a.fn();//A this===a 9 a.fn.call({name:'B'});//B this==={name:'B'} 10 11 var fn1=a.fn; 12 fn1();//this===window
2.this的几种使用情况:
*作为构造函数执行
1 function Foo(){ 2 this.name='shangsan'; 3 } 4 var f = new Foo(); 5 f.name //"shangsan"
*作为对象属性执行
1 var obj={ 2 name:'A', 3 printName:function(){ 4 console.log ( this === obj ); // true 5 console.log(this.name); //A 6 } 7 } 8 obj.printName();
*作为普通函数执行
1 function fn(){ 2 console.log(this);//this===window 3 } 4 fn();
*call apply bind
一般来说,this总是指向调用某个方法的对象,但是使用call()和apply()、bind()方法时,就会改变this的指向。
1 function fn(name,age){ 2 console.log(name);//lisi 3 console.log(this);//{x: 100} 4 } 5 fn.call({x:100},'lisi',30);