持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第10天,点击查看活动详情
前言
简单分析一下ES5的预解析和this指向问题
变量提升(预解析)
代码在执行时会创建执行上下文(执行环境)
执行环境会有两个阶段
- 创建阶段(做准备)
- 执行阶段(开始执行)
console.log(a); //undefined
var a = 1;
//以上代码执行过程:
var a; // a的值为undefined 创建阶段。
console.log(a); // 打印的值为undefined 执行阶段
a=1; // 执行阶段
console.log(a); // undefined
注意事项
- 不管是全局执行环境还是函数执行环境每个执行环境都会存在提升的操作
- 函数表达式不会被提升
- 函数声明和变量都会被提升,但是函数将会被首先提升,然后才是变量
foo();
var foo = function (){ //is not function: typeError
console.log('....');
}
通过一道预解析的练习题来具体剖析一下预解析
在结果没出来之前先试着输出你的答案(7个输出)
console.log(a);
var a = 0;
console.log(a);
function fn() {
console.log(a);
a = 1;
console.log(a);
}
fn();
var fn = function () {
console.log(a);
var a = 0;
console.log(a++);
}
fn();
console.log(a);
图解剖析此题
7个打印结果如下图解析
this
什么是this
- 一个关键字,一个引用变量
- this在函数中可以直接使用
- this在函数执行的时候才确定指向
this的调用方式
- 全局环境中的this就是window
console.log(this) //window - 如果是没有前缀的调用也是属于window的调用,可以简单的理解为光秃秃的调用this也是指向window的,如下所示:
function fn(){
function test(){
console.log(this) //window
}
test()
}
fn()
- 如果是通过对象的方法调用,this指向这个对象(包括上下文对象调用)
function foo(){
console.log(this.a);
}
var obj = {
a:2,
foo:foo
}
function doFoo(fn){ //fn=obj.foo
fn(); //fn();//window
}
var a = 'gs';
doFoo(obj.foo); //gs
call apply bind 强制绑定
call,apply,bind是Function对象原型对象上自带的三个方法,所有的函数都能调用
- 改变函数执行时的上下文,或者改变函数调用时的this指向 指向call、apply、bind的第一个参数
确定this指向的方法
- 先看有没有强制绑定
- 再看是不是实例化调用
- 看是否有上下文对象调用
- 默认绑定 这样来判断的话基本是不会错的
好了,以上就是本篇文章的分享,感谢阅读!