前端乱弹99日之奇怪的this 上集

2018-06-03  本文已影响18人  业余马拉松选手

作为一个Java后端狗转来的人,对于this指针的理解,可能还是有点痛的,这次我就“涨着胆子”来说下这个问题吧
首先看这样一个方法

function a(){
  console.log(this);
}
a();

如果是在浏览器里执行,应该是返回window对象
这里其实有一个最基本的原则:
this的值通常是有所在函数的执行环境所决定,也就是看函数是如何调用的。
如果上面这段代码是在Node服务器里执行的,返回的就应该是一个global对象,而不是window对象。
这里,我们也可以称为全局对象。
那么接着我们看一个稍微复杂点的例子

var b = {
  name : "I'm b",
  say : function(){
    console.log(this);
    console.log(this.name);
  }
}
b.say();

这时在浏览器返回如下:

 {name: "I'm b", say: ƒ} name: "I'm b"say: ƒ ()__proto__: Objectconstructor: ƒ Object()hasOwnProperty: ƒ hasOwnProperty()isPrototypeOf: ƒ isPrototypeOf()propertyIsEnumerable: ƒ propertyIsEnumerable()toLocaleString: ƒ toLocaleString()toString: ƒ toString()valueOf: ƒ valueOf()__defineGetter__: ƒ __defineGetter__()__defineSetter__: ƒ __defineSetter__()__lookupGetter__: ƒ __lookupGetter__()__lookupSetter__: ƒ __lookupSetter__()get __proto__: ƒ __proto__()set __proto__: ƒ __proto__()

I'm b

上面一行显示的是我们创建的对象的情况,根据上面的原则,执行say这个方法的时候,是在b这个对象的执行环境下,所以this也就指向了这里。

那么接着我们再继续看下这个例子

var b = {
  name : "I'm b",
  say : function(){
    var updateName = function(newName){
     this.name = newName;
    }
    updateName("I'm Big B");
    console.log(this);
    console.log(this.name);
  }
}
b.say();

如果按照正常的理解,这时b的对象的名称应该改为了I'm Big B,但结果却有点出乎意料,就算是执行了updateName这个方法,但b对象的name的值并未改变,但如果你 console.log(window.name) 就会发现这个值是I'm Big B
是不是有点奇怪?
嗯,这里updateName这个值所指向的函数,其实与b这个对象并没有包含关系,如果要实现updateName这个方法可以修改b对象所指向的name值的话,可以这样做:

var b = {
  name : "I'm b",
  say : function(){
    var self = this;
    var updateName = function(newName){
     self.name = newName;
    }
    updateName("I'm Big B");
    console.log(self);
    console.log(self.name);
  }
}
b.say();

这样就能达到你的效果啦~
关于这个奇怪的this指针的效果,今天还只是初步聊了下,下节会详细分析~~

上一篇下一篇

猜你喜欢

热点阅读