this的學(xué)習(xí)
解析器在調(diào)用函數(shù)時,每次都會向函數(shù)內(nèi)部傳遞一個隱含的參數(shù)this,
這個隱含參數(shù)就是this, this指向的是一個對象,
這個對象我們稱為函數(shù)執(zhí)行的上下文對象
根據(jù)函數(shù)的調(diào)用方式的不同,this會指向不同的對象
1.以函數(shù)的形式調(diào)用時,this指向的是window
2.以方法的形式調(diào)用時,this就是調(diào)用方法的那個對象
3.當(dāng)以構(gòu)造函數(shù)的形式調(diào)用時,this就是新創(chuàng)建的那個對象
4.使用call()和apply()調(diào)用時,this就是call()和apply()第一個參數(shù)的對象
5.使用bind()()調(diào)用時,this就是bind()第一個參數(shù)的對象
*this 永遠指向最后調(diào)用它的那個對象**
functionfn(){ ?
? ??
? ? ? ? console.log(this);//window
}
fn();
上面例子直接執(zhí)行函數(shù),這時的this指向window
下面再來個例子:
function fn(){
??
?console.log(this);
}
let obj = {
??
?name: '阿離王',
?
??fn: fn,
};
obj.fn();
這時上面的例子打印的this 指向 obj對象了
let name = '全局name';
function fn(){
?
?console.log(this.name);
}
let obj = {
?
?name: '阿離王',
?
??fn:fn
};
let obj2 = {
??
?name: '張三',
?
?fn
}
fn(); // 全局name
obj.fn();
// 阿離王
使用new關(guān)鍵詞調(diào)用的函數(shù),是構(gòu)造函數(shù)(constructor)
構(gòu)造函數(shù)是專門用來創(chuàng)建對象的函數(shù)
構(gòu)造函數(shù)就是一個普通的函數(shù),
不同的是,構(gòu)造函數(shù)習(xí)慣上函數(shù)名首字母大寫(不成文規(guī)范)
構(gòu)造函數(shù)和普通函數(shù)的區(qū)別就是調(diào)用方式的不同
普通函數(shù)是直接調(diào)用,而構(gòu)造函數(shù)需要使用new關(guān)鍵字來調(diào)用
構(gòu)造函數(shù)的執(zhí)行流程:
1.立刻創(chuàng)建一個新的對象(在內(nèi)存開辟一個新空間)
2.將新建的對象設(shè)置為函數(shù)中的this的指向新建的對象,在構(gòu)造函數(shù)中可以使用this來引用新建的對象
3.逐行執(zhí)行函數(shù)中的代碼
4.將新建的對象作為返回值返回
使用同一個構(gòu)造函數(shù)創(chuàng)建的對象,我們稱為一類對象
,也將一個構(gòu)造函數(shù)稱為一個類
我們將通過一個構(gòu)造函數(shù)創(chuàng)建的對象,稱為是該類的實例, new 一個構(gòu)造函數(shù),我們稱為實例化一個對象出來
function Person(name, age){?
?? ?this.name = name;
?
? ??this.age = age;
?
?this.sayName = function(){
? ?
? ?console.log(this.name);
?
? ??}
}
let per = new Person('阿離王', 28);
let per1 = new Person('張三', 20);
let per2 = new Person('李四', 19);
console.log(per);
console.log(per1);
console.log(per2.sayName());
function Dog(){
}
let dog = new Dog();
console.log(dog);
call() 和 apply()
這兩個方法都是函數(shù)對象的方法,需要通過函數(shù)來調(diào)用
當(dāng)對函數(shù)調(diào)用call()和apply()都也會調(diào)用原函數(shù)
在調(diào)用call()和apply()時,第一個參數(shù)為一個對象 此時這個對象將會成為函數(shù)執(zhí)行時的this
function fn(a, b){
?
?console.log(a, b);
?
?console.log(this);
}
let obj = {name: 'yu'};
fn.call(obj, 1, 2);
fn.apply(obj, [3, 4]);
let obj2 = {
??
?name: '阿離王',
?
??sayName: function(){
? ?
? ?console.log(this.name);
?
?}
}
let obj3 = {name: 'obj3'}
obj2.sayName.call(obj3);
bind()
bind() 是創(chuàng)建一個新的函數(shù),我們必須要手動去調(diào)用:
所以得寫成bind()()
function fn(a, b){
??
?console.log(a, b);
?
??console.log(this);
}
let obj = {name: 'yu'};
fn.call(obj, 1, 2);
fn.apply(obj, [3, 4]);
fn.bind(obj, 5, 6)();
點擊參考 this call() apply() bind()的詳細介紹