this是js中的一個關鍵字,函數運行時自動生成的一個內部對象,只能在函數內部使用。咱們要討論的是 this 的指向。web
this就是函數運行時自動生成的一個內部對象數組
this的指向不是在建立時就決定了,而是由執行環境決定的。app
下面介紹一下幾種狀況下,this的指向函數
全局環境下,this就表明window對象。(針對web 應用來說)this
var name = 'zhar'; function say(){ console.log(this.name);//zhar } say();
一樣,在 setTimeout 或 setInterval 這樣的延時函數中調用也屬於全局對象spa
var name = 'zhar'; setTimeout(function(){ console.log(this.name);//zhar },0);
對象環境指向對象。指針
var obj = { name : "zhar", say : function(){ console.log(this.name);//zhar } } obj.say();
下面舉兩個經典的例子:code
var name = 'tom'; var obj = { name : "zhar", say : function(){ console.log(this.name); } } var fun = obj.say; fun();//輸出 ?//tom-->fun定義在全局環境下,即window.fun() //再次說明了this的指向是由運行時的執行環境來決定的
var name = 'tom'; var obj = { name : "zhar", say : function(){ return function(){ console.log(this.name); } } } obj.say()();//輸出 ?//tom
構造函數中的this 會指向建立出來的實例對象,使用new 調用構造函數時,會先建立出一個空對象,而後用call函數把構造函數中的this指針修改成指向這個空對象。執行完環境後,空對象也就有了相關的屬性,而後將對象返回出去,因此說就不用咱們本身手動返回啦~對象
function Person() { this.name = 'zhar'; } var p = new Person(); console.log(p.name);
綜合以上,構造函數不須要返回值,若是咱們指定一個返回值時,this的指向將發生變化繼承
function Person() { this.name = 'zhar'; return {}; } var p = new Person(); console.log(p.name);//undefined //-------------------------------------- function Person() { this.name = 'zhar'; return {name:'tom'}; } var p = new Person(); console.log(p.name);//tom 若是構造函數返回對象(Object,Array,Function),那 this 將指向這個對象,其它基礎類型則不受影響 //-------------------------------------- function Person() { this.name = 'zhar'; return 1;//number string boolean 等 } var p = new Person(); console.log(p.name);//zhar
因此,如無必要咱們一般不要設置構造函數的返回值
在 DOM 事件中使用 this,this 指向了觸發事件的 DOM 元素自己
li.onclick = function(){ console.log(this.innerHTML); }
總結下來就是一句話:是誰調用的,this就指向誰
下面介紹一下如何來修改this 的指向
var name = "zhar"; var obj = { name : "zhar", say : function(){ var _this = this;//使用一個變量指向 this setTimeout(function(){ console.log(_this.name); },0); } } obj.say();
該方法爲很是經常使用的一個方法
首先說明一下,call也是函數調用的一種形式,能夠經過 函數名.call()來調用函數。可是提供了一個修改this指向的方法。
fun.call(thisObj[,arg1[,arg2[,...]]])
調用方式和傳入參數如上面的形式。其中,因此call(thisObj[,arg1[,arg2[,...]]])中的第一個參數就是要更改this指向的對象,爲必選參數; 以後的參數要根據調用的函數是否須要傳入參數(爲可選的)
下面經過代碼來展現call 如何使用:
var name = 'zhar'; function say(){ console.log(this.name); }; say();//zhar; var obj = { name : 'tom', say : function(){ console.log(this.name); } } say.call(obj);//tom 將 say 函數中的 this 替換爲傳入的對象 obj.say();//tom obj.say.call(null);//zhar 將 obj.say 函數的 this 替換爲了 null,也就意味着指向了全局環境
//前面課程的繼承代碼 function Person(){ this.name = "人"; } function Student(){ Person.call(this,null); } var s = new Student(); console.log(s.name);
li.onclick = function(){ console.log(this.innerHTML);//此處的 this 表明着 DOM 元素 function update(){ this.innerHTML += " new "; } //update();//這樣作的話,this 的指向將變爲window update.call(this);//經過 call 方法修改函數內 this 的指向 }
//call 的傳參 function say(arg1,arg2){ console.log(this.name,arg1,arg2); }; var obj = { name : 'tom', say : function(){ console.log(this.name); } } say.call(obj,'one','two');//tom one two
apply
apply的做用和call同樣,不一樣的是傳參的形式。apply須要以數組的形式傳遞參數
//apply 的傳參 function say(arg1,arg2){ console.log(this.name,arg1,arg2); }; var obj = { name : 'tom', say : function(){ console.log(this.name); } } say.apply(obj,['one','two']);//tom one two
以上就是關於this指向和如何修改this指向的介紹
做者:丶灰太狼他叔 連接:https://www.jianshu.com/p/8d357981dedb 來源:簡書 簡書著做權歸做者全部,任何形式的轉載都請聯繫做者得到受權並註明出處。