javascript中this,apply,call,bind的學(xué)習(xí)筆記

一 、關(guān)于this

Javascript中的this經(jīng)常讓人糊涂,但總的一個原則就是,this總是指向一個對象,而具體指向哪個對象是在javascript執(zhí)行階段由執(zhí)行環(huán)境動態(tài)綁定的,而非在javascript初始化階段聲明時的環(huán)境

實際中,this的指向大概分為以下四類:

(1) 作為對象的方法調(diào)用

(2) 作為普通函數(shù)調(diào)用

(3) 構(gòu)造器調(diào)用

(4) Function,prototype.call或Function.prototype.apply,動態(tài)的改變出入函數(shù)的this

1.作為對象的方法調(diào)用時,this指向改對象

var obj = {

name:"xiaoming",

age:25,

say:function(){

alert(this === obj);

alert("我叫" + this.name + "我今年" + this.age + "歲");

}

};

obj.say();

2.作為普通函數(shù)調(diào)用,this總是指向全局對象window

alert(this); ?//window

var name = "xiaoming";

function getName(){

return this.name;

}

alert(getName()); //xiaoming

3. 構(gòu)造器調(diào)用, 當用 new 運算符調(diào)用函數(shù)時,該函數(shù)總是會返回一個對象,通常情況下,構(gòu)造函數(shù)里的 this 就指向返回的這個對象

function Person(){

this.name = "xiaoming";

}

var xiaoming = new Person();

alert(xiaoming.name);

在構(gòu)造函數(shù)中還有一種特例,那就是在構(gòu)造函數(shù)中顯示的返回一個對象,那這個this就不跟我們期待的一樣了,例如:

function Person(){

this.name = "xiaoming";

return {

name:"我是另外一個xiaoming"

}

}

var which = new Person();

alert(which.name); //我是另外一個xiaoming


二 、接下來說說apply.call,bind的區(qū)別以及他們中的this

var xiaoming = {

name:"xiaoming",

age:25,

say:function(){

console.log("我叫"+this.name+",我今年"+this.age+"歲了。");

}

}

var xiaoli = {

name:"xiaoli",

age:27

}

xiaoming.say() //很明顯,就是"我叫xiaoming,我今年25歲了"

//如果我現(xiàn)在想打印出xiaoli的名字,怎么辦呢?那就用到了call,apply.bind

//他們的作用就是改變this指向的對象

xiaoming.say.call(xiaoli);

xiaoming.say.apply(xiaoli);

xiaoming.say.bind(xiaoli)();

從以上代碼中我們發(fā)現(xiàn)call.bind,apply都可以改變this的指向,但是好像call和apply沒什么區(qū)別呀?難道兩個的作用是一樣的?答案是當然不一樣。

bind的區(qū)別已經(jīng)很明顯了,bind后面需要加一個(),這又是為什么呢?

這是因為call和apply直接返回的是函數(shù)調(diào)用后的結(jié)構(gòu),而bind方法返回的是一個函數(shù),不信,你可以typeof一下,看返回的是不是function哦。

好,接下來解決call和apply到底有什么區(qū)別呢?如果現(xiàn)在我把代碼改一下

var xiaoming = {

name:"xiaoming",

age:25,

say:function(school,hobby){

console.log(this.name+"|"+this.age+"|"+school+hobby);

}

}

var xiaoli = {

name:"xiaoli",

age:27

}

xiaoming.say.call(xiaoli,"shcool1","羽毛球");

xiaoming.say.apply(xiaoli,["school1","羽毛球"])

從上面可以看出,他們的區(qū)別無非就是傳參的形式不一樣,apply必須把參數(shù)放進數(shù)組

三、最后再來說說bind方法

bind方法就是把函數(shù)綁定到一個對象上。但里面有一點坑是,用bind返回的函數(shù),它是沒有prototype屬性的。

四 .另外apply和call還能繼承

function Person(name,age){

this.name = name;

this.age = age;

}

function student(name,age,className){

Person.call(this,name,age);

this.className = className;

}

var Amy = new student("Amy",25,"一年級");

console.log(Amy.age)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容