JavaScript中的this,call,apply使用及區(qū)別詳解
學(xué)習(xí)起因:
在之前的JavaScript學(xué)習(xí)中,this,call,apply總是讓我感到迷惑,但是他們的運(yùn)用又非常的廣泛。遂專門花了一天,來弄懂JavaScript的this,call,apply。
中途參考的書籍也很多,以《JavaScript設(shè)計(jì)模式與開發(fā)實(shí)踐》為主,《JavaScript高級程序設(shè)計(jì)》、《你不知道的JavaScript》為輔。這三本書對我理解this,call,apply都起了很大的幫助。
this
首先,我們先講述this。
在《JavaScript設(shè)計(jì)模式與開發(fā)實(shí)踐》關(guān)于this的描述中,我認(rèn)為有一句話切中了this的核心要點(diǎn)。那就是:
JavaScript的this總是指向一個(gè)對象
具體到實(shí)際應(yīng)用中,this的指向又可以分為以下四種:
- 作為對象的方法調(diào)用
- 作為普通函數(shù)調(diào)用
- 構(gòu)造器調(diào)用
- apply和call調(diào)用
接下來我們?nèi)テ饰銮?點(diǎn),至于第4點(diǎn)的apply和call調(diào)用,會(huì)在call和apply部分詳細(xì)講解。
1.作為對象的方法調(diào)用
說明:作為對象方法調(diào)用時(shí),this指向該對象。
舉例:
/**
* 1.作為對象的方法調(diào)用
*
* 作為對象方法調(diào)用時(shí),this指向該對象。
*/
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總是指向全局對象(瀏覽器中是window)。
舉例:
/**
* 2.作為普通函數(shù)調(diào)用
*
* 不作為對象屬性調(diào)用時(shí),this必須指向一個(gè)對象。那就是全局對象。
*/
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在全局對象中調(diào)用,自然讀取的是全局對象的name值
var theName = myObject.getName;
theName(); // 'globalName'
3.構(gòu)造器調(diào)用
說明:作為構(gòu)造器調(diào)用時(shí),this指向返回的這個(gè)對象。
舉例:
/**
* 3.作為構(gòu)造器調(diào)用
*
* 作為構(gòu)造器調(diào)用時(shí),this指向返回的這個(gè)對象。
*/
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其它對象,那么this將不起作用。
如果return的是別的數(shù)據(jù)類型,則沒有問題。
var myClass = function() {
this.name = "Lxxyx";
// 加入return時(shí),則返回的是別的對象。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.借用其它對象的方法
這兒,我們先以一個(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對象的原型方法。
原理也很容易理解,比如剛才調(diào)用的是push方法,而push方法在谷歌的v8引擎中,源代碼是這樣的:
function ArrayPush() {
var n = TO_UINT32(this.length); // 被push對象的長度
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ù)組對象,都可以調(diào)用相關(guān)方法去處理。
這部分內(nèi)容比較復(fù)雜,再加上自己水平也不太夠。所以推薦有條件的同學(xué)去購買相關(guān)書籍,或者等我的后續(xù)博客文章。
感想
通過對這部分的學(xué)習(xí),算是加深了對JavaScript的理解。最直觀的表現(xiàn)就是,去看一些優(yōu)秀框架的源代碼時(shí),不再是被this,call,apply,bind繞的暈乎乎的。還是很開心的~
下一段時(shí)間,準(zhǔn)備深入探索一下日常學(xué)習(xí)和使用的CSS。畢竟JavaScript學(xué)了,HTML和CSS也不能落下。
- JavaScript中的apply()方法和call()方法使用介紹
- js中繼承的幾種用法總結(jié)(apply,call,prototype)
- javascript中apply和call方法的作用及區(qū)別說明
- 詳解js中的apply與call的用法
- JS中改變this指向的方法(call和apply、bind)
- JavaScript中的apply和call函數(shù)詳解
- js中call與apply的用法小結(jié)
- js apply/call/caller/callee/bind使用方法與區(qū)別分析
- JS面向?qū)ο?、prototype、call()、apply()
- JavaScript學(xué)習(xí)點(diǎn)滴 call、apply的區(qū)別
- 詳解JS中的this、apply、call、bind(經(jīng)典面試題)
- 淺談javascript中call()、apply()、bind()的用法
- JavaScript中apply與call的用法意義及區(qū)別說明
- js中apply()和call()的區(qū)別與用法實(shí)例分析
- 跟我學(xué)習(xí)javascript的call(),apply(),bind()與回調(diào)
- javascript call和apply方法
- 深入理解JavaScript中的call、apply、bind方法的區(qū)別
- 再談JavaScript中bind、call、apply三個(gè)方法的區(qū)別與使用方式
相關(guān)文章
JavaScript 基本數(shù)據(jù)類型轉(zhuǎn)換你了解嘛
這篇文章主要為大家介紹了JavaScript基本數(shù)據(jù)類型轉(zhuǎn)換,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助2022-01-01
window.navigate 與 window.location.href 的使用區(qū)別介紹
首先說明的是 window.navigate 與 window.location.href 都是實(shí)現(xiàn)頁面鏈接跳轉(zhuǎn)的,下面將介紹它們的區(qū)別。感興趣的朋友可以參考下2013-09-09
JavaScript 鏈?zhǔn)浇Y(jié)構(gòu)序列化詳解
這篇文章主要介紹了JavaScript 鏈?zhǔn)浇Y(jié)構(gòu)序列化詳解的相關(guān)資料,需要的朋友可以參考下2016-09-09
詳解JS-- 浮點(diǎn)數(shù)運(yùn)算處理
本篇文章主要介紹了JS--浮點(diǎn)數(shù)運(yùn)算處理,現(xiàn)在分享給大家,也給大家做個(gè)參考。感興趣的小伙伴們可以參考一下。2016-11-11
Javascript入門學(xué)習(xí)資料收集整理篇
為大家更好的接觸和學(xué)習(xí)js資料,所以我轉(zhuǎn)了這篇文章,我大約的看了下,文章寫的非常不錯(cuò),希望大家不要急,慢慢看,第一次看不懂不要緊,多練習(xí)就可以了2008-07-07
淺談javascript中onbeforeunload與onunload事件
javascript中onbeforeunload與onunload事件就是頁面加載前與頁面關(guān)閉時(shí)的兩個(gè)功能的函數(shù),可以防止頁面刷新時(shí)給提示再刷新或頁面關(guān)閉時(shí)給出提示,下面我來介紹onbeforeunload與onunload事件用法。2015-12-12

