javascript
javascript 之 this 用法
參考視頻:http://www.imooc.com/video/6430
JavaScript中的this比較靈活,也是讓很多初學者摸不到頭腦,那么根據在不同的環境下,在同一個函數,不同的調用方式下,那么這個this也有可能是不同的。
我們先來看,全局作用于下的this。
全局的this(瀏覽器)
console.log(this.document===documet);//true
console.log(this===window);//true
this.a=37;
console.log(window.a);//37
全局作用域下的this一般指的是全局對象,在瀏覽器里面一般指的是windows。比如上面的this.document就是window.document. 這里的this就相當于window,所以this=window.
so,this.a=window.a。
?
一般函數的this(瀏覽器)
function f1(){
return this;
}
f1()===window;//true,global object
比如我們用這樣的一般函數聲明和一般表達式,然后我們直接去調用這樣的函數的話,那么這里面的this仍然指向全局變量,那么在瀏覽器里面就是window,那么在node.js里面呢,就是global對象。
function f2(){
"use strict"//ee strict mode
return this;
}
f2()===undefined;//true
我們需要注意的一點就是嚴格模式下呢,一般函數調用的this會指向這個undefined.
?
我們更常見的作為對象方法的函數的this:
var o={
prop:37,
f:function(){
return this.prop;
}
};
console.log(o.f());//logs 37
是將this作為對象方法去用的時候,我們知道,函數呢,如果作為一個對象的屬性,比如我們這創建的自變量o,那么o里面有個屬性f,它的值是一個函數對象,那對于這樣一個把函數作為一個對象屬性值的方式,我們常常叫做一個對象的方法。那么多為對象方法去調用的時候,比如這里的用o.f()去調用,這種情況的this一般會指向這樣一個對象o,這里我們可以看到o.f()調用以后會返回37,因為this指向了o,所以相當于o.prop,所以最終的結果是37。
?
var o={prop:37};
function independent(){
return this.prop;
}
o.f=independent;
console.log(o.f());//logs 37
那么這里面,我們不止是一定要定義成函數自變量的對象,比如這里面我們定義了一個對象o,只有一個屬性prop:37;那么這里面我們有個獨立的independent函數,那么這里面的函數,我們仍然return?this.prop,如果我直接去調用independent的話,則this依舊指向window。這里臨時創建一個o的屬性f(即是o.f)并且指向independent,所以這樣再調用console.log(o.f(),則又跟上一條函數同理!
這里面是不是看函數是怎么創建的,而是只要將這個函數作為對象的方法,就像這個o.f()去調用的話,那么,這個this,就會指向這個o.prop。
對象原型鏈上的this:
var o={f:function(){return this.a+this.b;}};
var p=Object.create(o);
p.a=1;
p.b=4;
console.log(p.f());//5
創建一個對象o里面有屬性f,并且函數作為屬性的值,我們通過Object.create創建了一個對象p,而對象P是一個空對象,并且它的原型指向了o,那么p.a=1;p.b=4;這樣創建了對象的屬性,那么我去調用它原型上方法的時候,this.a和this.b依舊能取到p.a和p.b的值。這里面p的原型才是o,也就是說,調用p.f()的時候調用的時候這個對象原型對象上的o上面的屬性f。
get/set方法與this:
function ?modulus(){
return Math.aqrt(thisre*this.re+this*this.im);
}
var 0={
re:1,
im:-1,
get phase(){
return Math.atan2(this.im,this.re);
}
};
Object.defineProperty(o,'modules',{
get:modulus,enumerable,configurable:ture});
console.log(o.phase,o.modulus);//logs-0.78 ? 14.4142
get/set方法也是類似的,這里用的是一個modules。然后這里我們去計算this.re和this.im,這里我們用一個對象o,并且o里面有一個get方法,給這樣的屬性phase,再用
Object.defineProperty(object, propertyname, descriptor)去定義o的屬性,這里我們同樣可以調用o.phase和o.modulus去拿到o的屬性,那么modules里面的this依舊會指向o的re和im,我們也要知道get/set方法里面的this也是會指向它所在的那個對象里面,那么我們臨時動態區別一下O這個對象與創建.modulus的屬性也是類似的,那么這一點上,和一般的對象屬性作為函數對象也是類似的!構造器中的this:
function MyClass(){
this.a=37;
}
var o= new MyClass();
console.log(o.a);//37
function C2(){
this.a=37;
return{a:38};
}
o=new C2();
console.log(o.a);//38
如果我們正常去調用MyClass這個函數的話,this就是指向全局變量window,但是如果用new MyClass來把它作為構造器去調用的話,那么MyClass的this會指向空的對象,并且這個對象會指向原型MyClass.prototype.這里使用了new以后,那么這個this會指向一個原型為MyClass.prototype屬性的這樣一個空對象,那么這樣由于我們的this.a賦值了37,而且MyClass的返回值默認是this,所以這對象o就會輸出37。那么類似的我們定義了一個函數C2,然后this.a=37,但是return里面的返回的語句是a:38,所以a就不再是37了,而是38。當我們使用new來創建這樣一個構造器來這樣去調用的時候,那么這樣的this會指向一個原型為MyClass.prototype這樣一個空對象,最后還是要看返回值,如果你沒有寫return語句,則默認返回this,如果有return語句返回了一個對象的話,所以會將return的對象作為返回值,所以o.a就是38.
call/apply方法與this:
function add(c,d){
return this.a+this.b+c+d;
}
var 0= {a:1,b:3};
add.call(,o,5,7);//1+3+5+7=16
add.apply(o,[10,20]);//1+3+10+20=34
function bar(){
console.log(Object,prototype.toString.call(this));
}
bar.call(7);//"[object Number]"
除了不同的調用方式,每一個函數對象也會有方法,可以去修改函數執行時的里面的this,比較常見的就是call/apply。比如我這里面的函數聲明add,我們用this.a和this.b,和參數c和d把這四個數相加起來。我們是怎么做的呢,我們是定義一個變量o,里面有兩個屬性a:1,b:3,然后通過這個對象的的call方法,把第一個參數接受那個關于this的對象,后面是5和7(也就是我們想添加的參數),也就是c=5,d=7,最終的結果是就1+3+5+7=16。其實call和apply其實沒有什么差別,只是call和apply傳參的方式不同,call是直接把參數變量傳輸進去的,而apply是將參數作為數組的形式傳輸進去,所以apply的結果是也是1+3+10+20=34,。現在我們來區分一下情況下用到這個call和apply,比如說,我們想調用Object,prototype.toString,但是我們想指定某一個this的時候,來調用一些我們無法直接調用的一些方法,那么我們這里去調用bar。call(7),這樣就能拿到內部的這樣一個標簽間接的字符串。
bind方法與this:
function f(){
return this.a;
}
var g=f.bind({a:"test"});
console.log(g());//test
var o={a:37,f:f,g:g};
console.log(o.f(),o.g());//37 test
除了call/apply還有bind方法,bind方法只能兼容IE9以上版本,我們定義了一個函數對象f(),然后我們通過bind的方法,定義了一個a的對象,并把參數值“test”傳進去,這樣我們就得到了一個g對象,我們到下面調用輸出的時候,發現已經調用了test這個參數,這樣是采用了綁定一次,并重復去調用,仍然實現這種綁定的話,這樣會比我們使用call/apply高效一點。我們下面又定義了一個函數o,然后把a賦值為37,然后f賦值了f(),g賦值了g(),然后我們輸出的o.f(),o.g()是37,test.這里比較特殊的就是我們使用了bind方法,即使我們使用了bind方法,并把新綁定方法作為對象的屬性去調用,那么這里依舊會按照之前的綁定去走,所以也就返回這個test
轉載于:https://www.cnblogs.com/Yirannnnnn/p/4343378.html
總結
以上是生活随笔為你收集整理的javascript 之 this 用法的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 转iOS性能优化:Instruments
- 下一篇: gradle idea java ssm