执行上下文、this

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);

 

posted @ 2018-05-08 18:09  郑叶叶  阅读(625)  评论(2编辑  收藏  举报