這篇文章主要介紹了javascript中this屬性,小編覺得挺不錯的,現在分享給大家,也給大家做個參考。一起跟著小編過來看看吧
this總是回傳一個物件,也就是傳回屬性或方法目前所在的對象。
物件的屬性可以賦給另一個對象,所以屬性所在的目前物件是可變的,也就是this的指向是可變的。
eg:
var A = { name : '张三', describe : function(){ return '姓名:' + this.name; } }; var B = { name : '李四' } B.describe = A.describe; B.describe();
結果:「姓名:李四」
再看一個例子:
var A = { name : '张三', describe : function(){ return '姓名:' + this.name; } }; var name = '李四' f = A.describe; f();
結果也是“姓名:李四”,因為這時this指向f執行階段所在的物件-頂層window
this的使用場合
##1、全域環境——無論this是不是在函數內部,只要是在全域環境下運行,this就是指頂層物件window2、建構函數——指的是實例物件eg:var Obj = function(p){ this.p = p; } Obj.prototype.a = function(){ return this.p; } var obj = new Obj('color'); obj.a(); obj.p;結果是都回傳"color"上面程式碼定義了一個建構函式Obj,由於this指向實例對象,所以在Obj中定義this.p,相當於定義實例物件有一個p屬性,然後m方法可以回傳這個p屬性。 3、物件的方法
var obj = { foo : function(){ console.log(this); } }; obj.foo();//obj只有直接在obj物件上呼叫foo方法,this才會指向obj,其他用法時,this都指向程式碼區塊目前所在的物件。 情況一:(obj.foo = obj.foo)()——window情況二:(false || obj.foo)()——window #情況三:(1 , obj.foo)()——window上述程式碼中,obj.foo先運算再執行,即使它的值沒有變化,this也不再指向obj了4、Node在Node中,若在全域環境裡,this指向global,模組環境中,this指向module.exports
this使用注意點
1、避免多層thisvar o = { f1 : function(){ console.log(this); var f2 = function(){ console.log(this); }(); } } o.f1();執行結果是:{f1: ƒ}Window {decodeURIComponent: ƒ, postMessage: ƒ, blur: ƒ, focus: ƒ, close: ƒ, …}為什麼f2中的this指向的是全域物件呢?因為上面那段程式碼的執行過程其實是
var temp = function(){ console.log(this); }; var o = { f1 : function(){ console.log(this); var f2 = temp(); } } o.f1();解決方法一-在第二層改用一個指向外層this的變數
var o = { f1 : function(){ console.log(this); var that = this; var f2 = function(){ console.log(that); }(); } } o.f1();使用一個變數固定this的值,然後內層呼叫這個變量,是非常有用且大量應用的方法解決方法二-使用嚴格模式,在嚴格模式下,如果函數內部的this指向頂層物件就會報錯。 2、避免在陣列處理方法中使用this
var o = { v : 'hello', p : ['a1','a2'], f : function(){ this.p.forEach(function(item){ console.log(this.v + ' ' + item); }); } } o.f();結果:undefined a1undefined a2#導致這個結果的原因跟上一段的多層this是一樣的解決方法一——使用中間變數
var o = { v : 'hello', p : ['a1','a2'], f : function(){ var that = this; this.p.forEach(function(item){ console.log(that.v + ' ' + item); }); } } o.f();解決方法二——將this當作forEach方法的第二個參數,固定它的運行環境
var o = { v : 'hello', p : ['a1','a2'], f : function(){ this.p.forEach(function(item){ console.log(this.v + ' ' + item); },this); } } o.f();3、避免回呼函數中的this
var o = new Object(); o.f = function(){ console.log(this === o); } o.f();//true $("#button").on("click",o.f);//false
#綁定this的方法
JavaScript提供了call、apply、 bind三個方法來切換/固定this的指向function.prototype.call()
函數實例的call方法可以指定函數執行時this所在的作用域,call方法的參數量個對象,如果參數為空、null、undefined,則預設傳入全域對象。如果call的參數不是對象,那麼就會自動包裝成包裝對象。 func.call(thisValue,arg1,arg2,……)var n = 123; var obj = {n : 456}; function a(){ console.log(this.n); } a.call();//123 a.call(null);//123 a.call(undefined);//123 a.call(window);//123 a.call(obj);//456call方法的一個應用是呼叫物件的原生方法
var obj = {}; //原生方法 obj.hasOwnProperty('toString');//false //覆盖了原生的方法 obj.hasOwnProperty = function(){ return true; } obj.hasOwnProperty('toString');//true //调回原生的方法 Object.prototype.hasOwnProperty.call(obj,'toString');//false
function.prototype.apply()
apply與call唯一的區別是apply接受一個數組作為函數執行時的參數,func.apply(thisValue,[arg1,arg2,……])apply的應用之一-找出陣列的最大元素var a = [10,3,4,2]; Math.max.apply(null,a);apply的應用程式之二-將陣列的空元素變成undefined(因為陣列的forEach方法會跳過空元素,卻不會跳過undefined)
?
var a = ['a','','b']; function print(i){ console.log(i); } a.forEach(print);//a b Array.apply(null,a).forEach(print);//a undefined b運行結果跟上面不太一樣,都是a bapply的應用之三-轉換類似數組的物件
Array.prototype.slice.apply({0:1,length:1});apply的應用程式之四-綁定回呼函數的物件
var o = new Object(); o.f = function(){ console.log(this === o); } var f = function(){ o.f.apply(o);//或o.f.call(o); } $("#button").on("click",f);function.prototype.bind()bind方法用於將函數體內的this綁定到某個對象,然後傳回一個新函數下面的例子在將方法賦值後會出錯
var d = new Date(); d.getTime(); var print = d.getTime; print();//Uncaught TypeError: this is not a Date object.解決方法:
var print = d.getTime.bind(d);bind比call和apply更進一步的是,除了綁定this以外,還可以綁定原函數的參數
var add = function(x,y){ return x * this.m + y * this.n; } var obj = { m:2, n:2 } var newAdd = add.bind(obj,5);//绑定add的第一个参数x newAdd(5);//第二个参数y對於那些不支援bind方法的老式瀏覽器,可以自行定義bind方法
if(!('bind' in Function.prototype)){ Function.prototype.bind = function(){ var fn = this; var context = arguments[0]; var args = Array.prototype.slice.call(arguments,1); return function(){ return fn.apply(context,args); } } }
以上是詳解javascript中this屬性的詳細內容。更多資訊請關注PHP中文網其他相關文章!