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