javascript中this的指向初探

吐槽君 分类:javascript

在前端开发中this的指向问题是一个非常基础也很重要的知识点,是开发人员绕不过去的一个问题。那么今天用几个面试题来聊一聊前端中this问题吧.

首先需要知道一点:this 永远指向最后调用它的那个对象,通俗一点就是指向他爹。

this 指向

案例 1

this.value = "value";
function fn() {
  var value = "innerValue";
  console.log(this.value);
}
fn(); // value
 

这个题大家应该都知道答案肯定是打印value,那么为什么打印的结果是value呢?看刚才那句话this 永远指向最后调用它的那个对象,这个时候我们就想了究竟是谁调用了fn呢?其实就是window,这个时候我们就清楚了,哦原来是widnow调用了fn,所以这个this就指向了window,因此就输出打印value

案例 2

this.num = 30;
const obj = {
  num: 20,
  fn: function () {
    console.log(this.num);
  },
};
obj.fn(); // 20
var fn = obj.fn;
fn(); // 30
 

分析:

  1. 默读三遍this 永远指向最后调用它的那个对象,this 永远指向最后调用它的那个对象,this 永远指向最后调用它的那个对象
  2. 根据案例1的思路,是obj调用的fn,函数内部this指向的是obj,所有打印输出obj.num的值20
  3. 接下来我们声明了一个全局变量fn=obj.fn,调用fn()等同于调用window.fn(),所有打印输出window.num的值30

案例 3

难度加大一点

this.a = 20;
function go() {
  console.log(this.a);
  this.a = 30;
}
go.prototype.a = 40;
var test = {
  a: 50,
  init: function (fn) {
    fn();
    console.log(this.a);
    return fn;
  },
};
//输出1
console.log(new go().a);
// 输出2
test.init(go);
var p = test.init(go);
p();
 

在做这个题目之前,首先有一个知识点需要清楚,代码如下,首先会找对象的值,然后再去找原型对象的值。也就是说p.a的时候会先在对象上获取这个值,没有则在原型对象上获取,明白了这个就好了。

function P() {
    this.a = 1
}
P.prototype = 2
let p = new P()
console.log(p.a) // 1
 

分析:

  1. 首先实例化一个对象new go(),同时调用函数go,代码执行console.log(this.a),此时的this是指向实例化对象,按照 刚才的所说的,先找对象上的key值,发现没有,然后找原型对象上的a,发现go.prototype.a = 40所以打印40,同时this.a = 30,然后获取new go().a重复上一步的思路,先读取对象的key值发现存在且为30,所以整个的结果就是先输出40,然后输出30

  2. 调用test.init(go),首先调用go方法,我们可以这里理解test.init(window.go),其实就是调用window.go(),首先打印this.a,也就是window.a,发现全局声明了this.a=20,所以打印20,同时注意接下来的this.a=30,已经将全局的a改变了此时的window.a=30,接下来执行console.log(this.a);,此时的this指向test,所以输出打印50因此最后的结果就是先输出20,然后50

  3. 执行var p = test.init(go),重复步骤2首先调用全局函数go,打印全局的a,步骤2中更改了全局a的值为30,所以先输出30,然后调用test对象的init方法,执行console.log(this.a),因此打印50,最后定义了一个全局p,并返回了一个函数go,执行p(),也就是执行window.p(),此时的window.a===30所以打印30最终的输出就是30,50,30

  4. 综合以上分析最终的输出就是40,30,20,50,30,50,30

回复

我来回复
  • 暂无回复内容