關(guān)鍵詞:
- call:
- 語法:obj.call(thisObj, arg1, arg2, ...);
- 定義:調(diào)用一個(gè)對(duì)象的一個(gè)方法年柠,以另一個(gè)對(duì)象替換當(dāng)前對(duì)象砾医。
- apply:
- 語法:obj.apply(thisObj, [arg1, arg2, ...]);
- 定義:應(yīng)用某一對(duì)象的一個(gè)方法矾麻,用另一個(gè)對(duì)象替換當(dāng)前對(duì)象。
看這樣一個(gè)例子封救,搞清楚this的指向問題
function add(a, b){console.dir(this);}
function sub(c, d){console.dir(this);}
add(1,2); // Window
sub(1,2); // Window
add.call(sub, 1, 2); // sub(a, b)
sub.apply(add, [1, 2]); // add(a, b)
我們看到肮之,通過apply和call方法改變了this的指向,但是這么做并不會(huì)當(dāng)前改變函數(shù)的執(zhí)行衣摩,我們?cè)賮砜匆粋€(gè)例子昂验。
function add(j, k){
console.log(j+k);
}
function sub(j, k){
console.log(j-k);
}
add(5,3); //8
add.call(sub, 5, 3); //8
add.apply(sub, [5, 3]); //8
sub(5, 3); //2
sub.call(add, 5, 3); //2
sub.apply(add,[5,3]); //2
可以看到,使用call和apply方法對(duì)函數(shù)的正常執(zhí)行不會(huì)產(chǎn)生任何影響艾扮。
那我們用apply和call有什么用既琴,答:實(shí)現(xiàn)屬性的繼承
先來考慮一個(gè)問題,能不能實(shí)現(xiàn)對(duì)象之間繼承呢泡嘴?
var Superior = {
name :"長者",
age: 55
}
var Inferior = {};
console.log(Inferior); //Object {} ,空對(duì)象
Superior.call(Inferior); //TypeError:Superior.call is not a function
很遺憾地說甫恩,對(duì)象是不能使用call方法的,只有函數(shù)或函數(shù)表達(dá)式才可以
var Superior = function(){
this.name = "長者";
this.age = 55;
}
var Inferior = {};
console.log(Inferior); //Object {} ,空對(duì)象
Superior.call(Inferior);
console.log(Inferior); //Object {name: "長者", age: 55}
Inferior.name = "霧凇"
console.log(Superior.name);
var s = new Superior;
console.log(s.name); // 長者
這樣酌予,我們就把superior的屬性傳給了inferior磺箕,并且這種傳遞不會(huì)對(duì)superior造成任何影響。
現(xiàn)在抛虫,我們對(duì)上面的代碼做些改動(dòng)松靡,我們把inferior寫成函數(shù)表達(dá)式的形式
var Superior = function(){
this.name = "長者";
this.age = 55;
}
console.dir(Superior);
var Inferior = function(){
};
console.log(Inferior); // function (){}
Superior.call(Inferior);
console.log(Inferior); // function (){}
在使用了call和apply方法之后還是個(gè)空函數(shù),并沒有起作用建椰,那現(xiàn)在我們?cè)撛趺崔k呢雕欺?
有一種屬性的繼承方法叫做構(gòu)造函數(shù)偽裝
,我在[面向?qū)ο蟮睦^承][]中有介紹棉姐,讓我們?cè)賮砀膭?dòng)一下吧
[面向?qū)ο蟮睦^承]:http://www.reibang.com/p/693332d54ddf
var Superior = function(){
this.name = "長者";
this.age = 55;
}
console.dir(Superior);
var Inferior = function(){
Superior.call(this);
};
var s = new Inferior;
console.dir(s.name); // 長者
運(yùn)行之后屠列,我們發(fā)現(xiàn)inferior成功繼承了superior的屬性,鼓掌哈哈(o)/~~
為了鞏固加深印象伞矩,我們?cè)谧鲆粋€(gè)小測(cè)試吧
function Animal(name) {
this.name = name;
this.showName = function() {
console.log(this.name);
};
}
function Cat(name) {
Animal.call(this, name);
}
Cat.prototype = new Animal();
function Dog(name) {
Animal.apply(this, name);
}
Dog.prototype = new Animal();
var cat = new Cat("Black Cat"); //call必須是object
var dog = new Dog(["Black Dog"]); //apply必須是array
cat.showName();
dog.showName();
console.log(cat instanceof Animal); //true
console.log(dog instanceof Animal); //true
測(cè)試完畢脸哀!
call和apply還有一個(gè)妙用就是輸出數(shù)據(jù)類型
var a = {};
var b = [];
console.log(Object.prototype.toString.call(a)); // 輸出為: "[object Object]"
console.log(Object.prototype.toString.call(b)); // 輸出為: "[object Array]"
console.log(Object.prototype.toString.apply(a)); // 輸出為: "[object Object]"
console.log(Object.prototype.toString.apply(b)); // 輸出為: "[object Array]"
具體有多少種方式能判斷數(shù)據(jù)類型請(qǐng)看我的博客文章[js判斷數(shù)據(jù)類型深度解析][]
[js判斷數(shù)據(jù)類型深度解析]:http://www.reibang.com/p/ee1faf553e51