欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

JavaScript中的this,call,apply使用及區(qū)別詳解

 更新時(shí)間:2016年01月29日 08:45:45   投稿:hebedich  
本文結(jié)合基本javascript的權(quán)威書籍中的內(nèi)容,根據(jù)自己的理解,通過相關(guān)示例向大家展示了javascript中this,call,apply使用及區(qū)別,非常的細(xì)致全面,希望大家能夠喜歡。

學(xué)習(xí)起因:

在之前的JavaScript學(xué)習(xí)中,this,call,apply總是讓我感到迷惑,但是他們的運(yùn)用又非常的廣泛。遂專門花了一天,來弄懂JavaScript的this,call,apply。

中途參考的書籍也很多,以《JavaScript設(shè)計(jì)模式與開發(fā)實(shí)踐》為主,《JavaScript高級(jí)程序設(shè)計(jì)》、《你不知道的JavaScript》為輔。這三本書對(duì)我理解this,call,apply都起了很大的幫助。

this

首先,我們先講述this。

在《JavaScript設(shè)計(jì)模式與開發(fā)實(shí)踐》關(guān)于this的描述中,我認(rèn)為有一句話切中了this的核心要點(diǎn)。那就是:

JavaScript的this總是指向一個(gè)對(duì)象
具體到實(shí)際應(yīng)用中,this的指向又可以分為以下四種:

  1. 作為對(duì)象的方法調(diào)用
  2. 作為普通函數(shù)調(diào)用
  3. 構(gòu)造器調(diào)用
  4. apply和call調(diào)用

接下來我們?nèi)テ饰銮?點(diǎn),至于第4點(diǎn)的apply和call調(diào)用,會(huì)在call和apply部分詳細(xì)講解。

1.作為對(duì)象的方法調(diào)用

說明:作為對(duì)象方法調(diào)用時(shí),this指向該對(duì)象。
舉例:

/**
 * 1.作為對(duì)象的方法調(diào)用
 *
 * 作為對(duì)象方法調(diào)用時(shí),this指向該對(duì)象。
 */

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

obj.getA(); // true , 1

2.作為普通函數(shù)調(diào)用

說明:作為普通函數(shù)調(diào)用時(shí),this總是指向全局對(duì)象(瀏覽器中是window)。
舉例:

/**
 * 2.作為普通函數(shù)調(diào)用
 *
 * 不作為對(duì)象屬性調(diào)用時(shí),this必須指向一個(gè)對(duì)象。那就是全局對(duì)象。
 */

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'

// 這里實(shí)質(zhì)上是把function() {console.log(this.name)}
// 這句話賦值給了theName。thisName在全局對(duì)象中調(diào)用,自然讀取的是全局對(duì)象的name值
var theName = myObject.getName;

theName(); // 'globalName'

3.構(gòu)造器調(diào)用

說明:作為構(gòu)造器調(diào)用時(shí),this指向返回的這個(gè)對(duì)象。
舉例:

/**
 * 3.作為構(gòu)造器調(diào)用
 * 
 * 作為構(gòu)造器調(diào)用時(shí),this指向返回的這個(gè)對(duì)象。
 */

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

var obj = new myClass();

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

但是如果構(gòu)造函數(shù)中手動(dòng)指定了return其它對(duì)象,那么this將不起作用。
如果return的是別的數(shù)據(jù)類型,則沒有問題。

var myClass = function() {
 this.name = "Lxxyx";
 // 加入return時(shí),則返回的是別的對(duì)象。this不起作用。
 return {
  name:"ReturnOthers"
 }
};

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

4.Call和Apply

Call和Apply的用途一樣。都是用來指定函數(shù)體內(nèi)this的指向。

Call和Apply的區(qū)別

Call:第一個(gè)參數(shù)為this的指向,要傳給函數(shù)的參數(shù)得一個(gè)一個(gè)的輸入。
Apply:第一個(gè)參數(shù)為this的指向,第二個(gè)參數(shù)為數(shù)組,一次性把所有參數(shù)傳入。

如果第一個(gè)參數(shù)為null,則this指向調(diào)用的本身。

1.改變this指向

說明:這是call和apply最常用的用途了。用于改變函數(shù)體內(nèi)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.借用其它對(duì)象的方法

這兒,我們先以一個(gè)立即執(zhí)行匿名函數(shù)做開頭:

(function(a, b) {
 console.log(arguments) // 1,2
 // 調(diào)用Array的原型方法
 Array.prototype.push.call(arguments, 3);
 console.log(arguments) // 1,2,3
})(1,2)

函數(shù)具有arguments屬性,而arguments是一個(gè)類數(shù)組。
但是arguments是不能直接調(diào)用數(shù)組的方法的,所以我們要用call或者apply來調(diào)用Array對(duì)象的原型方法。
原理也很容易理解,比如剛才調(diào)用的是push方法,而push方法在谷歌的v8引擎中,源代碼是這樣的:

function ArrayPush() {
 var n = TO_UINT32(this.length); // 被push對(duì)象的長(zhǎng)度
 var m = % _ArgumentsLength(); // push的參數(shù)個(gè)數(shù)
 for (var i = 0; i < m; i++) {
  this[i + n] = % _Arguments(i); // 復(fù)制元素
 }
 this.length = n + m; //修正length屬性
 return this.length;
}

它只與this有關(guān),所以只要是類數(shù)組對(duì)象,都可以調(diào)用相關(guān)方法去處理。

這部分內(nèi)容比較復(fù)雜,再加上自己水平也不太夠。所以推薦有條件的同學(xué)去購(gòu)買相關(guān)書籍,或者等我的后續(xù)博客文章。

感想

通過對(duì)這部分的學(xué)習(xí),算是加深了對(duì)JavaScript的理解。最直觀的表現(xiàn)就是,去看一些優(yōu)秀框架的源代碼時(shí),不再是被this,call,apply,bind繞的暈乎乎的。還是很開心的~

下一段時(shí)間,準(zhǔn)備深入探索一下日常學(xué)習(xí)和使用的CSS。畢竟JavaScript學(xué)了,HTML和CSS也不能落下。

相關(guān)文章

最新評(píng)論