摘要:出現(xiàn)箭頭函數(shù)的時(shí)候,指向?yàn)槎x時(shí)的上下文對象而非指向時(shí),并且不能被改變首先我們先看一個(gè)例子由上面的例子我們可以看出來此時(shí)指針在用改變了之后指向的依然是全局對象非嚴(yán)格瀏覽器環(huán)境中是而非。
javascript基礎(chǔ)之this指針
越往后面學(xué)越發(fā)現(xiàn)基礎(chǔ)的重要性,所以打算重新過一遍基礎(chǔ),之后出幾個(gè)vue和react的實(shí)戰(zhàn)教程。
ok,嚴(yán)歸正傳。
this是執(zhí)行上下文創(chuàng)建時(shí)確定的一個(gè)在執(zhí)行過程中不可改變的變量。
總之記住一句話this的指向由以執(zhí)行時(shí)候的上下文決定的而非定義時(shí)的上下文
看過一本書叫《JavaScript語言精粹》,里面把this的出現(xiàn)場景為4類,當(dāng)然那是在es6出來之前,不過也可以表示基本的用法了,在es6出來之后出現(xiàn)箭頭函數(shù),所以一共是5種:
有對象的就指向該對象
沒有對象的就指向全局對象,在非嚴(yán)格模式下指向window
有new構(gòu)造函數(shù)的就指向new完之后的新對象
通過apply或者bind或者call改變this指向的對象
出現(xiàn)箭頭函數(shù)的時(shí)候,this指向?yàn)槎x時(shí)的上下文對象而非指向時(shí),并且不能被call改變
函數(shù)有對象的時(shí)候就指向該對象let name = "bob"; let obj = { name, getName(){ console.log(this.name); } }; console.log(obj.getName()); //=>bob
因?yàn)間etName()屬于對象obj,并且由obj進(jìn)行調(diào)用,所以毫無疑問是指向obj這個(gè)對象,ok,我們再看一個(gè)例子
var name = "jay"; var obj = { name:"bob" getName(){ console.log(this.name); } }; let t = obj.getName; console.log(t()); // => jay
如上,為什么這次t函數(shù)打印出來的值是jay?excuse me?
其實(shí)要理解也好簡單,當(dāng)執(zhí)行t()的時(shí)候(在非嚴(yán)格模式下)其實(shí)t其實(shí)是屬于全局對象(在瀏覽器環(huán)境)也就是window,而var name = "jay"為全局變量,所以輸出jay也不奇怪了。
var name = "bob"; var obj = { name, getName:function(){ function otherName(){ return this.name; } console.log(otherName()); } }; obj.getName(); // =>bob
otherName隨便是在obj的getName中定義的,但是它還是一個(gè)普通函數(shù),他的this其實(shí)和
var name = "bob"; function otherName(){ return this.name; } console.log(otherName()); // =>bob
執(zhí)行效果一樣的,他的this的指向其實(shí)是undefined,在非嚴(yán)格模式下,當(dāng)this指向undefined的時(shí)候其實(shí)會(huì)自動(dòng)轉(zhuǎn)化成window對象(在瀏覽器中)。
ok,讓我們再看一種情況
var name = "bob"; function otherName(){ "use strict" return this.name; } console.log(otherName()); // Uncaught TypeError: Cannot read property "name" of undefined
這個(gè)時(shí)候會(huì)拋出一個(gè)錯(cuò)誤,因?yàn)樵趪?yán)格模式下當(dāng)this指針指向undefined的時(shí)候不會(huì)自動(dòng)轉(zhuǎn)化成window對象。
有new構(gòu)造函數(shù)的就指向new完之后的新對象首先什么是構(gòu)造函數(shù),其實(shí)可以用一句話去概括:
構(gòu)造函數(shù)其實(shí)就是用來新建對象的函數(shù)
JavaScript本身就為我們定義了幾個(gè)常用的構(gòu)造函數(shù),你肯定認(rèn)識(shí) 比如Function, Object, Array, Date等等,只不過我們平常object,function都不是用new Function,new Object,而是用他的語法糖比如
var obj = {} 其實(shí)等同于 var obj = new Object();
function Human(name,age,sex){ this.name = name; this.age = age; this.sex = sex; this.common = function(){ console.log("名字為"+this.name); } } var h = new Human("bob",25,"sex"); h.common(); // => 名字為bob
有new構(gòu)造函數(shù)的就指向new完之后的新對象,此時(shí)的this指向的是他new出現(xiàn)來的對象h。
通過apply或者bind或者call改變this指向的對象由于函數(shù)具有函數(shù)作用域,所以有時(shí)候我們需要引用外層作用域的時(shí)候通常用的方法是call,apply,和bind這三兄弟
首先我們來看看call,老樣子先看代碼
var a = { user:"bob", fn:function(){ console.log(this.user); } } var b = { user:"jay" } a.fn.call(b); // => jay
如果不調(diào)用call,我們直接使用a.fn的話將會(huì)輸出bob,因?yàn)閒n這個(gè)方法是a這個(gè)對象定義出來的,所以this指向是a這個(gè)對象,但是當(dāng)我們使用了call之后this指針指向的對象就變成b了,于是乎也不難理解為什么輸出的user是jay了。
簡介一下call的用法:
fn.call(obj,argument-1,argument-1,...)
是以obj這個(gè)對象去代替fn的this指針也就時(shí)fn的this指針指向obj,后面的argument-1,argument-1是形參
apply和call的用法基本相同,不同點(diǎn)是apply調(diào)用傳形參的時(shí)候穿的是數(shù)組或者是類數(shù)組,如下:
fn.apply(obj,[argument-1,argument-1,...])
至于bind和call或者apply的區(qū)別,我也舉一個(gè)例子
var a = { user:"bob", fn:function(){ console.log(this.user); } } var b = { user:"jay" } var c = a.fn.bind(b); c(); // => jay
從上面這個(gè)例子可以得出一個(gè)結(jié)論:
其實(shí)call和apply方法,都是對函數(shù)的直接調(diào)用,但是bind()方法需要加上()來執(zhí)行。
首先我們先看一個(gè)例子:
var obj = {name:"bob"}; var name = "jay"; var sayName = () => console.log(this.name); sayName(); // => jay sayName.call(obj); //jay
由上面的例子我們可以看出來此時(shí)this指針在用call改變了之后指向的依然是全局對象(非嚴(yán)格瀏覽器環(huán)境中是window)而非obj。
ok,至此this指針的用法總結(jié)完畢。
后記以上this的用法都為個(gè)人總結(jié),如有不當(dāng)之處還請指出
轉(zhuǎn)載請注明出處.
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/92684.html
摘要:系統(tǒng),扎實(shí)的語言基礎(chǔ)是一個(gè)優(yōu)秀的前端工程師必須具備的。第一個(gè)參數(shù)為調(diào)用函數(shù)時(shí)的指向,隨后的參數(shù)則作為函數(shù)的參數(shù)并調(diào)用,也就是。和的區(qū)別只有一個(gè),就是它只有兩個(gè)參數(shù),而且第二個(gè)參數(shù)為調(diào)用函數(shù)時(shí)的參數(shù)構(gòu)成的數(shù)組。 系統(tǒng),扎實(shí)的 javascript 語言基礎(chǔ)是一個(gè)優(yōu)秀的前端工程師必須具備的。在看了一些關(guān)于 call,apply,bind 的文章后,我還是打算寫下這篇總結(jié),原因其實(shí)有好幾個(gè)。...
摘要:應(yīng)該算是前期比較容易混淆的一個(gè)關(guān)鍵字了,在這里,我就打算按照我的理解來說一下首先呢,的值是跟運(yùn)行時(shí)被調(diào)用的位置相關(guān)的,而不是詞法作用域。來一個(gè)例子在瀏覽器中執(zhí)行,會(huì)發(fā)現(xiàn),如果作為一個(gè)函數(shù)單獨(dú)調(diào)用,那么指向的就是全局對象。 this應(yīng)該算是前期比較容易混淆的一個(gè)關(guān)鍵字了,在這里,我就打算按照我的理解來說一下 首先呢,this的值是跟運(yùn)行時(shí)被調(diào)用的位置相關(guān)的,而不是詞法作用域。 也就是說,...
摘要:本文是面向前端小白的,大手子可以跳過,寫的不好之處多多分鐘搞定常用基礎(chǔ)知識(shí)前端掘金基礎(chǔ)智商劃重點(diǎn)在實(shí)際開發(fā)中,已經(jīng)非常普及了。 JavaScript字符串所有API全解密 - 掘金關(guān)于 我的博客:louis blog SF專欄:路易斯前端深度課 原文鏈接:JavaScript字符串所有API全解密 本文近 6k 字,讀完需 10 分鐘。 字符串作為基本的信息交流的橋梁,幾乎被所有的編程...
摘要:如果有一方是布爾值,則轉(zhuǎn)換為,轉(zhuǎn)換為,再進(jìn)行判斷。等同運(yùn)算符類型不同返回類型相同如果同為數(shù)字字符串則比較值如果同為布爾值,相同則為不同為如果兩個(gè)操作數(shù)同為引用類型,且引用的為同一個(gè)對象函數(shù),數(shù)組,則相同。 本文主要記錄平時(shí)開發(fā)遇到的知識(shí)點(diǎn)和小技巧 相等判斷(==) 類型相同: 判斷其值是否相同 類型不同: 1. 如果數(shù)字和字符串比較, 則字符串會(huì)被隱式轉(zhuǎn)換為數(shù)字,在做判斷。 2....
摘要:在最開始的時(shí)候,原型對象的設(shè)計(jì)主要是為了獲取對象的構(gòu)造函數(shù)。同理數(shù)組通過調(diào)用函數(shù)通過調(diào)用原型鏈中描述了原型鏈的概念,并將原型鏈作為實(shí)現(xiàn)繼承的主要方法。 對象的創(chuàng)建 在JavaScript中創(chuàng)建一個(gè)對象有三種方式??梢酝ㄟ^對象直接量、關(guān)鍵字new和Object.create()函數(shù)來創(chuàng)建對象。 1. 對象直接量 創(chuàng)建對象最直接的方式就是在JavaScript代碼中使用對象直接量。在ES5...
閱讀 2627·2021-11-12 10:36
閱讀 2267·2021-08-23 09:47
閱讀 1689·2019-08-30 15:44
閱讀 1411·2019-08-30 14:10
閱讀 2249·2019-08-29 16:52
閱讀 2347·2019-08-29 16:40
閱讀 1594·2019-08-29 16:17
閱讀 2415·2019-08-26 13:21