一直以來都知道js的this讓初學者很困惑, 但因爲在學angularjs的時候潘老師早早的就教咱們寫代碼時先定義self = this
, 而後經過操做self
, 再以後學習angular又一直使用的箭頭函數, 因此js的this
用起來和java的用起來並無什麼不一樣, 也就沒有認真的去學習js的this
和其餘語言的到底獨特在那裏, 本週遇到了一個函數盡然不能使用箭頭函數, 又想起了這個問題, 就找了幾篇博客學了學。html
讓咱們先看幾段js代碼,並猜猜打印的是什麼java
下面的環境都爲chrome的控制檯, 即非嚴格模式(即不使用
use strict
, 兩種模式下結果不相同)
// 例子1 function a(){ name: 'yunzhi_a'; console.log(this); //? } a(); // 例子2 var b = { name:"yunzhi_b", fn:function(){ console.log(this) // ? } } b.fn(); // 例子3 var c = { name:"yunzhi_c", fn:function(){ console.log(this); // ? } } window.c.fn(); // 例子4 var d = { name: 'yunzhi_d', o: { name: 'object', fn: function(){ name: 'fn' console.log(this); // ? } } } var j = d.o.fn; j();
是否是感受他們都差很少?
公佈答案以前, 先說一下this的使用的規則:angularjs
this的指向在函數定義的時候是肯定不了的,只有函數執行的時候才能肯定this到底指向誰, 實際上this的最終指向的是那個調用它的對象
答案是
Window
,爲何呢?想一想上面的規則,**this的最終指向的是那個調用它的對象**
,函數沒有調用對象,這時this
將指向全局的window
對象。chrome
第二個應該很簡單了,仍是上面的規則,此次是b
調用的fn
,因此嘛app
第三個呢,是誰調用的fn
,window
嗎?再想一想
複習一下,this的最終指向的是那個調用它的對象
, fn()
是經過誰調用的,是c
調用的,因此打這時的this指向的就是c
ide
看着和上面是差很少的對吧?因此答案就是o
對吧?不對
再看看, 咱們調用的是j
,雖然他是經過fn
賦的值,但咱們確實調用的是前面沒有對象的j
, 在例子1
中已經說過了,此時會this
會指向window
。函數
在使用箭頭函數時咱們不會遇到這種讓人暈乎的this
指向問題post
箭頭函數保持它當前執行上下文的
詞法做用域不變,而普通函數則不會。換句話說,箭頭函數從包含它的詞法做用域中繼承到了
this
的值。
var object = { data: [1,2,3], dataDouble: [1,2,3], double: function() { console.log("this inside of outerFn double()"); console.log(this); // object return this.data.map(function(item) { console.log(this); // window return item * 2; }); }, doubleArrow: function() { console.log("this inside of outerFn doubleArrow()"); console.log(this); // object return this.dataDouble.map(item => { console.log(this); // objecgt return item * 2; }); } }; object.double(); object.doubleArrow();
是否是對map中的函數是誰調用的感到疑惑了?爲何是window
?
由於map中的函數是一個匿名函數,他並無調用者,想到上面的例子了吧,咱們能夠看一下map
的基本實現學習
// Array.map polyfill if (Array.prototype.map === undefined) { Array.prototype.map = function(fn) { var rv = []; for(var i=0, l=this.length; i<l; i++) rv.push(fn(this[i])); return rv;
直接使用的fn()
。this
this
在嚴格模式下指向undefined
。
大部分狀況下,開發者使用 this ,並不但願它指向全局 window 對象。嚴格模式幫咱們在使用this
關鍵詞時,儘可能少作搬起石頭砸本身腳的蠢事。
開發者能夠經過bind
、call
和 apply
來主動控制this的指向,固然這裏再也不細說,有興趣能夠看這篇文章——JS中call、apply、bind使用指南,帶部分原理。。