美文网首页
关于this的二三事

关于this的二三事

作者: 字母31 | 来源:发表于2017-05-18 20:35 被阅读0次

什么是this

this是JS中一个非常重要的关键字。this 就是你 call 一个函数时,传入的 context。任何形式的函数调用都可以写成call形式,传入的第一个参数就是this。

f(a,b)   等价于  f.call(undefined , a , b)
f.m.n(a,b)  等价于  f.m.n.call(f.m , a , b)
fn.call(context , p1 , p2)

所以当我们无法确定this时我们可以转换成call形式来确认this。

如何确定this

通常我们确定this会用以下方式

1、console.log(this)
2、查看API源代码
3、查看API相关文档

this的使用

全局变量

function f() {
  console.log(this); // window
}
var a=1
function f() {
  console.log(this.a); 
}
f()
//1

对象的方法

当A对象的方法被赋予B对象,该方法中的this就从指向A对象变成了指向B对象。所以要特别小心,将某个对象的方法赋值给另一个对象,会改变this的指向。

var obj ={
  foo: function () {
    console.log(this);
  }
};
obj.foo()  // obj

但是,只有这一种用法(直接在obj对象上调用foo方法),this指向obj;其他用法时,this都指向代码块当前所在对象(浏览器为window对象)。

(obj.foo = obj.foo)()
/ 等价于 /
(obj.foo = function () {
  console.log(this);
})()
//window

可以这样理解,obj和obj.foo储存在两个内存地址,简称为M1和M2。只有obj.foo()这样调用时,是从M1调用M2,因此this指向obj。但是,上面情况是直接取出M2进行运算,然后就在全局环境执行运算结果(还是M2),因此this指向全局环境。

避免多层this

由于this的指向是不确定的,所以切勿在函数中包含多层的this。

var o = {
  f1: function () {
    console.log(this);
    var f2 = function () {
      console.log(this);
    }();
  }
}
o.f1()
// Object
// Window

上面代码等价于

var temp = function () {
  console.log(this);
};
var o = {
  f1: function () {
    console.log(this);
    var f2 = temp();
  }
}

当我们把代码修改为

var o = {
  f1: function() {
    console.log(this);
    var that = this;
    var f2 = function() {
      console.log(that);
    }();
  }
}
o.f1()
// Object
// Object

上面代码定义了变量that,固定指向外层的this,然后在内层使用that,就不会发生this指向的改变。

避免数组处理方法中的this

数组的map和foreach方法,允许提供一个函数作为参数。这个函数内部不应该使用this。

var o = {
  v: 'hello',
  p: [ 'a1', 'a2' ],
  f: function f() {
    this.p.forEach(function (item) {
      console.log(this.v + ' ' + item);
    });
  }
}
o.f()
// undefined a1
// undefined a2

上面代码相当于

var temp = function(){
   o.p.forEach(function (item) {
      console.log(this.v + ' ' + item);
    });
} //this指向全局变量
var o = {
  v: 'hello',
  p: [ 'a1', 'a2' ],
  f: temp() 
}
o.f()
// undefined a1
// undefined a2

我们同样可以这样修改

var o = {
  v: 'hello',
  p: [ 'a1', 'a2' ],
  f: function f() {
    var that = this;
    this.p.forEach(function (item) {
      console.log(that.v+' '+item);
    });
  }
}
o.f()
// hello a1
// hello a2

或者将this当作foreach方法的第二个参数,固定它的运行环境。

var o = {
  v: 'hello',
  p: [ 'a1', 'a2' ],
  f: function f() {
    this.p.forEach(function (item) {
      console.log(this.v + ' ' + item);
    }, this);
  }
}
o.f()
// hello a1
// hello a2

bind方法

bind方法用于将函数体内的this绑定到某个对象,然后返回一个新函数。

var counter = {
  count: 0,
  inc: function () {
    this.count++;
  }
};
var func = counter.inc;
func();
counter.count // 0
count // NaN

上面代码中,函数func是在全局环境中运行的,这时inc内部的this指向顶层对象window,所以counter.count是不会变的,反而创建了一个全局变量count。因为window.count原来等于undefined,进行递增运算后undefined++就等于NaN。

var func = counter.inc.bind(counter);
func();
counter.count
//1

使用bind方法将inc方法绑定到counter以后,再运行func就会得到正确结果。

小结

对于this,我们只要记得其本质就是call函数时传入的第一个参数,如果函数调用形式不是 call 形式,请将其转换为 call 形式,函数的this值可以用call改变,也可以用bind改变默认的this值。

相关文章

  • 关于NSArray的二三事

    关于NSArray的二三事

  • 关于String需要知道的二三事

    关于String需要知道的二三事 标签: Java基础 原文链接:关于String需要知道的二三事 转载请注明...

  • 关于,二三事

    备忘一 16. 12 .末 真的已经很久不码字 平时想要说的想要写的,断断续续的存在了备忘录里和记事本里 专门想要...

  • 关于this的二三事

    什么是this this是JS中一个非常重要的关键字。this 就是你 call 一个函数时,传入的 contex...

  • 关于绳的二三事

    对着茶杯发呆的我坐在候车室(发呆仅仅是我用来超然的一种方法,若身边有趣事我也不愿发呆:这并不是没有青春活力的体现!...

  • 关于早茶的二三事

    大年初八约了大学同学去吴忠吃早茶,与其说吃不如说是体验。与年华已逝,铅华历尽,多少有些分裂经历的中年女人一起,这...

  • 关于咖啡的二三事

    正经来说,我是一个对咖啡感兴趣的人,而不是热爱咖啡的人。这两者之间有一个最大的不同之处:一个喜欢喝咖啡,一个对咖啡...

  • 关于廊坊的二三事

    周六周日我们去了廊坊,去学习了米老师的小组经验,收获颇丰, 首先,他们极其注重学习方法的学习。他们甚至专门在刚开始...

  • 关于NSArray的二三事

    在iOS开发中,我们在非常非常多的地方用到了数组。而关于数组,有很多需要注意和优化的细节,需要我们潜入到下面,去了...

  • 关于学习的二三事

    1. 放学时,太郎一脸得意地走进我的办公室,手里拿着一张试卷。不用说,这次应该是又得了一百分。可嘴里却无所谓地说着...

网友评论

      本文标题:关于this的二三事

      本文链接:https://www.haomeiwen.com/subject/rsfexxtx.html