this的指向在函數定義的時候是肯定不了的,只有函數執行的時候才能肯定this到底指向誰,實際上this的最終指向的是那個調用它的對象。segmentfault
狀況1:若是一個函數中有this,可是它沒有被上一級的對象所調用,那麼this指向的就是window,這裏須要說明的是在js的嚴格版中this指向的不是window,而是指向調用函數的對象實例,這種函數中的this等於undefined。app
function a(){ var user = "維他奶"; console.log(this);//window console.log(this.user);//undefined } //windonw是全局對象,全部的全局變量都是對象的屬性. //a()<=>window.a() a(); console.log(window); console.log(window.user);//根本沒有user這個屬性。只有一個name="";
運行結果
函數
嚴格模式,請參照https://segmentfault.com/a/11...
嚴格模式下定義變量必須使用var。不然報錯.
在嚴格模式下,對象的函數中的this指向調用函數的對象實例
一樣道理,能夠推斷出,在嚴格模式下,構造函數中的this指向構造函數建立的對象實例。this
"use strict";//開啓嚴格模式 function a(){ var user = "維他奶"; //在嚴格模式下,對象的函數中的this指向調用函數的對象實例 console.log(this);//a{} console.log(this.user);//undefined } var A = new a();
運行結果spa
狀況2:若是一個函數中有this,這個函數有被上一級的對象所調用,那麼this指向的就是上一級的對象。code
var sum = { a:10, b:{ a:12, fn:function(){ console.log(this.a);//12 } } } sum.b.fn();
運行結果對象
狀況3:若是一個函數中有this,儘管這個函數是被最外層的對象所調用,this指向的也只是它上一級的對象.blog
var sum = { a:10, b:{ // a:12, fn:function(){ console.log(this.a);//undefined } } } sum.b.fn();
運行結果ip
注意事項
儘管對象b中沒有屬性a,這個this指向的也是對象b,由於this只會指向它的上一級對象,無論這個對象中有沒有this要的東西。內存
狀況4:this永遠指向的是最後調用它的對象,也就是看它執行的時候是誰調用的,狀況4中雖然函數fn是被對象b所引用,可是在將fn賦值給變量num的時候並無執行因此最終指向的是window,這和狀況3是不同的,狀況3是直接執行了fn。
var sum = { a1:10, b:{ a:12, fn:function(){ console.log(this.a1);//undefined console.log(this);//window } } } var num = sum.b.fn; num();
運行結果
function A(){ this.name = "維他奶"; } var a = new A(); console.log(a.name);//維他奶
運行結果
new關鍵字到底作了什麼?
(1) 建立一個新對象;
(2) 將構造函數的做用域賦給新對象(所以 this 就指向了這個新對象);原理:自動調用apply方法,將this指向這個空對象,這樣的話函數內部的this就會被這個空的對象替代。
(3) 執行構造函數中的代碼(爲這個新對象添加屬性);
(4) 返回新對象。
return 會把new建立的this覆蓋.
若是返回值是複雜數據類型,那麼this指向的就是那個返回的對象,若是返回值不是複雜數據類型那麼this仍是指向函數的實例。
function A(){ this.name = "維他奶"; return 1; } var a = new A(); console.log(a.name);//維他奶 function A(){ this.name = "維他奶"; return ; } var a = new A(); console.log(a.name);//維他奶 function A(){ this.name = "維他奶"; return function(){}; } var a = new A(); //傳入空函數,因此輸出一個空,而不是undefined console.log(a.name);//"" function A(){ this.name = "維他奶"; return null; } var a = new A(); console.log(a.name);//維他奶
簡單數據類型:string,boolean,number,undefined,null,NaN複雜數據類型: Object,Function,Array,String,Boolean,Number其中String,Boolean,Number,是自帶的封裝好的方法。簡單數據類型存放在內存的棧中,而複雜數據類型存放在內存的堆中,把地址存放在內存的棧中,先獲取地址,再讀取堆中數據。