this关键字

1.  this的涵义,this是什么

  • 不管是什么场合,this都有一个共同点:它总是返回一个对象;简单说,this就是属性或方法“当前”所在的对象。
  • JavaScript 语言之中,一切皆对象,运行环境也是对象,所以函数都是在某个对象之中运行,this就是函数运行时所在的对象(环境)。

2.  this的设计目的

  • 由于函数可以在不同的运行环境执行,所以需要有一种机制,能够在函数体内部获得当前的运行环境(context)。所以,this就出现了,它的设计目的就是在函数体内部,指代函数当前的运行环境。

3.  使用场合,使用注意事项

  • 使用场合
  1. 全局环境:全局环境使用this,它指的就是顶层对象window。
  2. 构造函数。
  3. 对象的方法:JavaScript 引擎内部,obj和obj.foo储存在两个内存地址,称为地址一和地址二。obj.foo()这样调用时,是从地址一调用地址二,因此地址二的运行环境是地址一,this指向obj。但是,如果是直接取出地址二进行调用,这样的话,运行环境就是全局环境,因此this指向全局环境。
  • 注意事项
  1. 避免多层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();
  }
}

// 严格模式下,如果函数内部的this指向顶层对象,就会报错。
var counter = {
  count: 0
};
counter.inc = function () {
  ‘use strict‘;
  this.count++
};
var f = counter.inc;
f()
// TypeError: Cannot read property ‘count‘ of undefined

 2. 避免数组处理方法中的 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

// 上面代码中,foreach方法的回调函数中的this,其实是指向window对象,因此取不到o.v的值。

// 将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

 3. 避免回调函数中的 this

var o = new Object();
o.f = function () {
  console.log(this === o);
}

// jQuery 的写法
$(‘#button‘).on(‘click‘, o.f);

// 上面代码中,点击按钮以后,控制台会显示false。原因是此时this不再指向o对象,而是指向按钮的 DOM 对象

4.  绑定this的方法

  • Function.prototype.call()
var obj = {};

var f = function () {
  return this;
};

f() === window // true
f.call(obj) === obj // true

// call方法还可以接受多个参数。

func.call(thisValue, arg1, arg2, ...)

//call的第一个参数就是this所要指向的那个对象,后面的参数则是函数调用时所需的参数。
  • Function.prototype.apply()
// apply方法的作用与call方法类似,也是改变this指向,然后再调用该函数。唯一的区别就是,它接收一个数组作为函数执行时的参数。

// 1. 找出数组最大元素
var a = [10, 2, 4, 15, 9];
Math.max.apply(null, a) // 15

// 2. 将数组的空元素变为undefined,空元素与undefined的差别在于,数组的forEach方法会跳过空元素,但是不会跳过undefined。
Array.apply(null, [‘a‘, ,‘b‘])
// [ ‘a‘, undefined, ‘b‘ ]

// 3. 转换类似数组的对象。
Array.prototype.slice.apply({0: 1, length: 1}) // [1]
Array.prototype.slice.apply({0: 1}) // []
Array.prototype.slice.apply({0: 1, length: 2}) // [1, undefined]
Array.prototype.slice.apply({length: 1}) // [undefined]
// 从上面代码可以看到,这个方法起作用的前提是,被处理的对象必须有length属性,以及相对应的数字键。

// 4. 绑定回调函数的对象
var o = new Object();

o.f = function () {
  console.log(this === o);
}

var f = function (){
  o.f.apply(o);
  // 或者 o.f.call(o);
};

// jQuery 的写法
$(‘#button‘).on(‘click‘, f);
  • Function.prototype.bind()
// bind()方法用于将函数体内的this绑定到某个对象,然后返回一个新函数。

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

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

 

this关键字

上一篇:Lc_704二分查找


下一篇:centos7以yum方式安装zabbix-agent客户端服务