在面向對象的語言中,this關鍵字的含義是明確且具體的,即指代當前對象。通常在編譯期肯定下來,或稱爲編譯期綁定。而在 JavaScript中,this是動態綁定,或稱爲運行期綁定的,這就致使JavaScript中的this關鍵字有能力具有多重含義,帶來靈活性的同時,也爲初學者帶來很多困惑。javascript
固然,仍是老話,全部的方法都來自網上,學到了纔是本身的!!html
而後,寫在前面,帶上咱們可愛的小夥伴。廢話很少說,下面咱們開始看起吧!
前端
文章主要是對js的this進行簡單的說明和介紹,順帶會添加一些代碼,沒辦法,語言能力有限,說明不了的只能直接上代碼了。java
關於JS中的this,這是不少前端面試必考的題目,有時候在網上看到這些題目,看着感受還不錯,作起來很是的酸爽!而在實際的開發中,也會遇到各類使用this的問題。固然,在剛開始的時候,咱們可能會很是的困惑,這個地方,爲何要這樣使用this尼?有時候不明白爲何不直接使用this,而要把this做爲參數傳入。git
下面,我將以個人理解的方式對this的理解和使用,作一個簡單的介紹。github
接單的理解:this指的是引用它的對象。面試
固然,也能夠套用輪子哥的一個解釋:編程
this在js的函數裏面只是一個參數,是經過Fuck.Shit(Bitches)這種語法來傳遞的,點號前面的表達式就算this。不要想太多。數組
通常來講,闡述JavaScript中this的運做機制,下面一句話詮釋的很是貼切。瀏覽器
When a function of an object was called, the object will be passed into the execution context as this value
簡而言之,就是function的this永遠指向調用它的對象。而鑑於JS所謂的「萬物皆對象」,這個this所以能夠是任何物件,好比Global對象
JavaScript有一套徹底不一樣於其它語言的對this的處理機制。 下面,將會在不一樣的狀況下,this指向的各不相同。
當在所有範圍內使用 this,它將會指向全局對象。
this; console.log(this);//輸出window
瀏覽器中運行的 JavaScript 腳本,這個全局對象是 window。
這裏this也會指向全局對象。
function foo(){ console.log(this); } foo();//輸出window
這個例子中,this 指向調用方法的對象。
var test = { foo : function(){ console.log(this); } } test.foo();//輸出test對象
若是函數傾向於和 new 關鍵詞一塊使用,則咱們稱這個函數是 構造函數。 在函數內部,this 指向新建立的對象。
function foo(name,age){ this.name = name; this.age = age; console.log(this); } new foo('yu',23);//輸出新建立的對象 foo {name: "yu", age: 23}
當使用Function.prototype上的call或者apply方法時,函數內的this將會被顯式設置爲函數調用的第一個參數。
所以函數調用的規則在上例中已經不適用了,在foo 函數內 this 被設置成了 bar。
function foo(a, b, c) { this.a = a; this.b = b; this.c = c; } var bar = {}; foo.apply(bar, [1, 2, 3]); // 數組將會被擴展,bar被修改成Object {a: 1, b: 2, c: 3} foo.call(bar, 4, 4, 4); // 傳遞到foo的參數是:a = 4, b = 4, c = 4; bar被修改成Object {a: 4, b: 4, c: 4}
這裏使用了apply和call方法,用於修改this指針的指向。會在後面的文章中詳細說明。
題目描述:
實現函數 callIt,調用以後知足以下條件
一、返回的結果爲調用 fn 以後的結果
二、fn 的調用參數爲 callIt 的第一個參數以後的所有參數
輸入例子:
var a = 1; var b = 2; var test = function (first, second) { return first === a && second === b; }; callIt(test, a, b);
輸出例子: true
代碼實現
//方法一 function callIt(fn) { var arr = [].slice.call(arguments,1); return fn.call(null, arr[0], arr[1]);//由於只有兩個參數,這裏直接使用兩個了 // } //方法二 function callIt(fn) { //Array.prototype.slice.call的做用是將arguments僞對象轉換成數組對象。 //下面的目的是,將arguments轉化爲數組後,截取第一個元素以後的全部元素 return fn.apply(this,[].slice.call(arguments,1));//這裏用[]代替Array.prototype,也可使用下面的。 //return fn.apply(this,Array.prototype.slice.call(arguments,1)); }
代碼說明:
首先,arguments不是真正的數組,不能直接使用slice方法,因此纔會用Array對象原型鏈上面的slice方法去處理arguments,返回的天然是一個數組。
另外,給apply/call傳遞null,「」空字符串,默認都是this
以上的全部方法,都來自網上。
全部的方法,都必須腳踏實地,在具體應用場景下去分析、去選擇,咱們應該按照具體的狀況,來選擇方法。
由於瀏覽器的多樣性,前端的應用場景常常很複雜,性能優化充滿挑戰,也充滿機遇。
學會了纔是本身的,知道會用會寫,纔是咱們最終的目標。