摘要:函數定義在全局作用域中,引用了對象,調用函數之前,的值并不確定,可能會在代碼執行過程中引用不同的對象。在全局環境中調用函數時,引用的就是全局對象。這兩個方法的用途都是在特定的作用域中調用函數,實際上等于設置函數體內對象的值。
本文首發于知乎專欄:前端指南
this是函數內部的一個特殊對象,它引用的是函數據以執行的環境對象。
全局環境下的this當在網頁的全局作用域中調用函數時,this對象引用的就是window。
console.log(this);//Window function f() { return this; } f();//Window
函數f()定義在全局作用域中,引用了this對象,調用函數之前,this的值并不確定,可能會在代碼執行過程中引用不同的對象。在全局環境中調用函數f()時,this引用的就是全局對象Window。
對象中的this將一個函數賦給對象,通過對象調用這個函數,它們的this是調用該函數的對象。
var o = { color: "blue", sayColor: function () { return this.color; } }; o.sayColor();//blue
將函數sayColor賦給對象o,o.sayColor()被調用時,函數內部的this被綁定到o
我們也可以用如下方法:
var o = { color: "blue" }; function sayColor() { return this.color; } o.sayColor = sayColor; o.sayColor();//blue
函數的名字僅僅是一個包含指針的變量,在何處定義調用函數不會影響到this的行為,全局的sayColor()與o.sayColor()指向的是同一個函數。
構造函數中的this函數或方法之前帶有關鍵字new,它就構成了構造函數調用。通過構造函數生成一個新的對象,this指向新對象、
function person() { this.name = "Jack"; } var o = new person(); console.log(o.name);//Jackapply和call
每個函數都包含兩個非繼承而來的方法,apply()和call()。這兩個方法的用途都是在特定的作用域中調用函數,實際上等于設置函數體內this對象的值。首先apply()方法接收兩個參數:一個是在其中運行函數的作用域,另一個是參數數組。其中,第二個參數可以是Array實例,也可以是 arguments對象。
function sum(num1, num2) { return num1 + num2; } function callSum1(num1, num2) { return sum.apply(this, arguments); } function callSum2(num1, num2) { return sum.apply(this, [num1, num2]); } console.log(callSum1(10, 10));//20 console.log(callSum2(10, 10));//20
上邊這個例子中,callSum1()在執行sum()函數時傳入了this作為this值(在作用域中調用的,傳入的就是window對象)和arguments對象。而callSum2()也調用了sum()函數,但傳入的是this和一個參數數組。
注:在嚴格模式下,未指定環境對象而調用函數,則this值不會被轉型為window,除非明確把函數添加到某個對象或者調用apply()或call(),否則this值是undefined。
call()與apply()方法作用相同,區別僅僅在于接收參數方式不同,對call()而言,第一個參數是this沒有變化,不同的是其余參數都直接傳遞給函數。換句話說,在使用call()方法時,傳遞給函數的參數必須逐個列舉出來。
function sum(num1, num2) { return num1 + num2; } function callSum(num1, num2) { return sum.call(this, num1, num2); } console.log(callSum(10, 10));//20
call()和apply()真正強大的地方在于能擴充函數賴以運行的作用域。
window.color = "red"; var o = { color: "blue" }; function sayColor() { console.log(this.color); } sayColor();//red sayColor.call(this);//red sayColor.call(window);//red sayColor.call(o);//blue
使用call()或者apply()擴充作用域最大的好處,就是對象不需要與方法有任何耦合關系。
bindES5還定義了bind,這個方法會創建一個函數的實例,其this值會被綁定傳給bind()函數的值
window.color = "red"; var o = { color: "blue" }; function sayColor() { console.log(this.color); } var objectSayColor = sayColor.bind(o); objectSayColor();//blue
在sayColor()調用bind()并傳入對象o,創建了objectSayColor()函數,該函數的this值等于o因此即使在全局作用域中調用這個函數,也會看到“blue”。
閉包中的this閉包中使用this對象可能會導致一些問題,this對象在運行時是基于函數的執行環境對象的:在全局函數中,this等于window,而當函數被作為某個對象方法調用時,this等于那個對象。匿名函數的執行環境具有全局性,因此其this對象通常指向window。
var color = "red"; var o = { name: "blue", sayColor: function () { return function () { return this.color; }; } } console.log(o.sayColor()());//red //改進 var o = { color: "blue", sayColor: function () { var that = this; return function () { return that.color; }; } } console.log(o.sayColor()());//blueES6中箭頭函數中的this
this引用的是函數據以執行的環境對象。但是在使用箭頭函數時,函數體內的this對象,就是定義時所在的對象,而不是使用時所在的對象。箭頭函數的使用可參考鏈接
http://es6.ruanyifeng.com/#do...
function foo() { setTimeout(() => { console.log("id:", this.id); }, 100) } var id = 21; foo.call({ id: 42 });//id:42
箭頭函數中的this指向foo的this,箭頭函數中也不存在arguments,指向外層函數foo對象的arguments。
由于箭頭函數沒有自己的this,所以也不能用call()、apply()、bind()改變this的指向。
綁定this函數綁定運算符是::,雙冒號是左邊是一個對象,右邊是一個函數。該運算符會自動將左邊的對象作為上下文環境(this對象),綁定到右邊函數上。詳細可參考鏈接
http://es6.ruanyifeng.com/#do...
foo::bar; //等同于 bar.bind(foo);
在判斷this指向時,要記住,在沒有綁定this的情況下,this動態綁定,指向運行時的環境,而非代碼中的位置,只有箭頭函數才是靜態綁定,將this綁定到代碼中的位置。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/82650.html
摘要:理解的函數基礎要搞好深入淺出原型使用原型模型,雖然這經常被當作缺點提及,但是只要善于運用,其實基于原型的繼承模型比傳統的類繼承還要強大。中文指南基本操作指南二繼續熟悉的幾對方法,包括,,。商業轉載請聯系作者獲得授權,非商業轉載請注明出處。 怎樣使用 this 因為本人屬于偽前端,因此文中只看懂了 8 成左右,希望能夠給大家帶來幫助....(據說是阿里的前端妹子寫的) this 的值到底...
摘要:和類在開始時遇到類組件,只是需要有關類的基礎。畢竟,中的條件呈現僅再次顯示大多數是而不是特定的任何內容。 在我的研討會期間,更多的材料是關于JavaScript而不是React。其中大部分歸結為JavaScript ES6以及功能和語法,但也包括三元運算符,語言中的簡寫版本,此對象,JavaScript內置函數(map,reduce,filter)或更常識性的概念,如:可組合性,可重用...
摘要:對象在中,除了數字字符串布爾值這幾個簡單類型外,其他的都是對象。那么在函數對象中,這兩個屬性的有什么區別呢表示該函數對象的原型表示使用來執行該函數時這種函數一般成為構造函數,后面會講解,新創建的對象的原型。這時的函數通常稱為構造函數。。 本文原發于我的個人博客,經多次修改后發到sf上。本文仍在不斷修改中,最新版請訪問個人博客。 最近工作一直在用nodejs做開發,有了nodejs,...
摘要:所以相同點是,在全局范圍內,全局變量終究是屬于老大的。只生效一次引入了。只生效一次在箭頭函數中,與封閉詞法環境的保持一致。我通常把這些原始函數叫做構造函數。在里面你可以嵌套函數,也就是你可以在函數里面定義函數。 showImg(https://img-blog.csdnimg.cn/20190522000008399.jpg?x-oss-process=image/watermark,...
摘要:原文許多人被中的關鍵字給困擾住了,我想混亂的根源來自人們理所當然地認為中的應該像中的或中的一樣工作。盡管有點難理解,但它的原理并不神秘。在瀏覽器中,全局對象是對象。運算符創建一個新對象并且設置函數中的指向調用函數的新對象。 原文:Understanding the this keyword in JavaScript 許多人被JavaScript中的this關鍵字給困擾住了,我想混亂的...
閱讀 1267·2023-04-25 23:22
閱讀 1668·2023-04-25 20:04
閱讀 2643·2021-11-22 15:24
閱讀 2801·2021-11-11 16:54
閱讀 1879·2019-08-30 14:03
閱讀 1480·2019-08-29 16:35
閱讀 1700·2019-08-26 10:29
閱讀 2643·2019-08-23 18:01