进修JavaScript之this,call,apply

进修原由:

在之前的JavaScript进修中,this,call,apply老是让我觉得疑惑,然则他们的运用又异常的普遍。遂特地花了一天,来弄懂JavaScript的this,call,apply。
半途参考的书本也许多,以《JavaScript设想形式与开辟实践》为主,《JavaScript高等程序设想》、《你不知道的JavaScript》为辅。这三本书对我明白this,call,apply都起了很大的协助。

this

起首,我们先报告this。

在《JavaScript设想形式与开辟实践》关于this的形貌中,我认为有一句话切中了this的中心要点。那就是:

JavaScript的this老是指向一个对象

细致到现实运用中,this的指向又能够分为以下四种:

  1. 作为对象的要领挪用

  2. 作为一般函数挪用

  3. 组织器挪用

  4. apply和call挪用

接下来我们去理会前3点,至于第4点的apply和call挪用,会在call和apply部份细致解说。

1.作为对象的要领挪用

申明:作为对象要领挪用时,this指向该对象。
举例:

/**
 * 1.作为对象的要领挪用
 *
 * 作为对象要领挪用时,this指向该对象。
 */

var obj = {
  a: 1,
  getA: function() {
    console.log(this === obj);
    console.log(this.a);
  }
};

obj.getA(); // true , 1

2.作为一般函数挪用

申明:作为一般函数挪用时,this老是指向全局对象(浏览器中是window)。
举例:

/**
 * 2.作为一般函数挪用
 *
 * 不作为对象属性挪用时,this必需指向一个对象。那就是全局对象。
 */

window.name = 'globalName';

var getName = function() {
  console.log(this.name);
};

getName(); // 'globalName'

var myObject = {
  name: "ObjectName",
  getName: function() {
    console.log(this.name)
  }
};

myObject.getName(); // 'ObjectName'

// 这里实质上是把function() {console.log(this.name)}
// 这句话赋值给了theName。thisName在全局对象中挪用,天然读取的是全局对象的name值
var theName = myObject.getName;

theName(); // 'globalName'

3.组织器挪用

申明:作为组织器挪用时,this指向返回的这个对象。
举例:

/**
 * 3.作为组织器挪用
 * 
 * 作为组织器挪用时,this指向返回的这个对象。
 */

var myClass = function() {
  this.name = "Lxxyx";
};

var obj = new myClass();

console.log(obj.name); // Lxxyx
console.log(obj) // myClass {name: "Lxxyx"}

然则假如组织函数中手动指定了return别的对象,那末this将不起作用。
假如return的是别的数据类型,则没有题目。

var myClass = function() {
  this.name = "Lxxyx";
  // 到场return时,则返回的是别的对象。this不起作用。
  return {
    name:"ReturnOthers"
  }
};

var obj = new myClass();
console.log(obj.name); // ReturnOthers

Call和Apply

Call和Apply的用处一样。都是用来指定函数体内this的指向。

Call和Apply的区分

Call:第一个参数为this的指向,要传给函数的参数得一个一个的输入。
Apply:第一个参数为this的指向,第二个参数为数组,一次性把一切参数传入。

假如第一个参数为null,则this指向宿主环境,在浏览器中则是window。(多谢批评中一波不是一波的斧正)

1.转变this指向

申明:这是call和apply最经常运用的用处了。用于转变函数体内this的指向。
举例:

var name = "GlobalName"

var func = function() {
  console.log(this.name)
};

func(); // "GlobalName"

var obj = {
  name: "Lxxyx",
  getName: function() {
    console.log(this.name)
  }
};

obj.getName.apply(window) // "GlobalName" 将this指向window
func.apply(obj) // "Lxxyx" 将this指向obj

2.借用别的对象的要领

这儿,我们先以一个马上实行匿名函数做开首:

(function(a, b) {
  console.log(arguments) // 1,2
  // 挪用Array的原型要领
  Array.prototype.push.call(arguments, 3);
  console.log(arguments) // 1,2,3
})(1,2)

函数具有arguments属性,而arguments是一个类数组。
然则arguments是不能直接挪用数组的要领的,所以我们要用call或许apply来挪用Array对象的原型要领。
道理也很轻易明白,比方适才挪用的是push要领,而push要领在谷歌的v8引擎中,源代码是如许的:

function ArrayPush() {
  var n = TO_UINT32(this.length); // 被push对象的长度
  var m = % _ArgumentsLength(); // push的参数个数
  for (var i = 0; i < m; i++) {
    this[i + n] = % _Arguments(i); // 复制元素
  }
  this.length = n + m; //修改length属性
  return this.length;
}

它只与this有关,所以只如果类数组对象,都能够挪用相干要领去处置惩罚。

这部份内容比较复杂,再加上本身程度也不太够。所以引荐有条件的同学去购置相干书本,或许等我的后续博客文章。

感受

经由过程对这部份的进修,算是加深了对JavaScript的明白。最直观的表现就是,去看一些优异框架的源代码时,不再是被this,call,apply,bind绕的晕乎乎的。照样很高兴的~

下一段时候,预备深切探究一下一样平常进修和运用的CSS。毕竟JavaScript学了,HTML和CSS也不能落下。

前端路漫漫,且行且歌。

末了附上本人博客地址和原文链接,愿望能与列位多多交换。

Lxxyx的前端乐土
原文链接:寒假前端进修(7)——进修JavaScript之this,call,apply

    原文作者:Lxxyx
    原文地址: https://segmentfault.com/a/1190000004380278
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞