一、被apply和call調用的函數中沒有傳遞參數
(一)不傳參數
結果:
(二)傳遞 null
結果:
總結:
1.當使用 apply和 call去調用函數並且沒有傳遞參數時,前提這個函數中也沒有傳遞參數,我們發現 他們的打印結果和 this 指向是相同的 都是指向window 此時相當於 f1() 調用函數 就相當於 f1.apply() 和 f1.call()
2.當傳遞 null 的時候,他們的指向也是相同的 都是指向 window
此時相當於 f1() 調用函數 就相當於 f1.apply(null) 和 f1.call(null)
(三)當傳遞一個具體對象時
結果:
我們發現 使用
f1.apply(stu)
和f1.call(stu)
去調用函數的時候,this的指向發生了改變,不再是 window,而是 Object
二、被 apply和 call 調用的函數中有參數傳遞
(一)apply和call不傳遞參數
結果:
總結:
apply和call沒有傳遞參數,所以沒有進行參數的運算,值是 NaN ,但是他們的this指向並沒有改變,仍然是 window
(二)當傳遞null時
結果:
總結:
與不傳參數的結果是一樣的,值是 NaN,並且this 指向沒有改變
(三)當傳入一個具體對象時
結果:
總結:
兩個方法傳入具體對象時,都改變了 this的指向,this 指向不是 window ,而是 Object
思考:
兩者都傳入一個對象改變了 this 指向,但是如何去傳入參數進行函數的運算呢???
(四)傳入多個參數
結果:
總結:
1.apply和call傳入的第一個參數表示 this 指向的對象
2.apply和call可以傳遞多個參數,只是他們傳遞參數的方式不一樣
3.apply是以數組的方式傳遞參數的
4.call是以參數列表的方式傳遞參數的,也就是通過一個一個的方式傳遞參數
(五)改變this指向,獲取對象中的屬性值
總結:
1.f1()函數調用時,this的指向是window,而window中沒有定義age這個屬性值,所以是 undefined
2.apply和call都改變了 this 的指向,this 指向了 stu ,stu這個對象中有 age 這個屬性值 ,所以輸出 age = 18
三、被apply和 call 調用的函數中有返回值
總結:
apply 和 call 都使用變量來接收函數的返回值
四、原型指向改變案例
function Person(food) {
this.food = food
}
// 通過原型來添加方法
Person.prototype.eat = function (x, y) {
console.log('我好想吃 ---->' + this.food)
console.log(x + y)
}
var per = new Person('大豬蹄')
per.eat(100, 100)
//創建 stu 對象,並添加屬性和方法
console.log('============================')
function Student(food) {
this.food = food
}
Student.prototype.study = function () {
console.log('禿頭少女的日常操作,天天敲代碼')
}
var stu = new Student('大雞腿')
//改變this指向,讓this指向 stu對象
//能調用 per對象中的方法
per.eat.apply(stu, [200, 200])
//也能調用自己的方法
stu.study()
結果:
五、總結apply與call
-
apply 的使用方式
函數名字.apply (對象,[參數1,參數2,...])
方法名字.apply (對象,[參數1,參數2,...]) -
call 的使用方式
函數名字.call (對象,參數1,參數2,...)
方法名字.call (對象,參數1,參數2,...) -
作用:改變this 的指向
-
區別:參數傳遞的方式不一樣
-
使用場景:只要是想使用別的對象的方法,並且希望這個方法是當前對象自己的,那么就可以使用 apply 或者 call 的方法 改變 this 的指向
六、bind 方法的使用
結果:
我們發現,雖然使用了bind 方法,但是它並沒有輸出內容,所以,要用一個變量接收一下,然后再調用
結果:
還可以寫成:
七、bind方法的案例
function Person(say){
this.say = say
}
Person.prototype.play = function(x,y){
console.log('做人嘛~~最重要的就是要開心吶!!' + this.say )
console.log(x+y)
}
var per = new Person('對呢對呢')
per.play(10,10)
//這是一條華麗的分割線
console.log('==============================================')
function Student(say){
this.say = say
}
Student.prototype.study = function(){
console.log('一根毛,兩根毛,頭上還有幾根毛')
}
var stu = new Student('撒花撒花')
//調用別人的方法
var ff = per.play.bind(stu)
ff(20,20)
//調用自己的方法
stu.study()
結果:
八、apply與call與bind之間的區別
相同點:
- 他們的作用都是相同的:改變 this 的指向
- 當他們不傳參數的時候,就跟直接調用函數或者方法的作用一樣,不改變this的指向
- 當只傳入 null 的,與上面作用也是一樣,不改變this的指向
不同點:
- apply 與 call 直接調用即可
- bind 要使用變量接收一下,然后再調用
- apply與call 是在調用的時候直接傳遞參數
- bind 可以在用變量接收的時候傳遞參數,也可以在接收后在調用中傳遞參數
- 傳遞參數的方式不一樣
- apply 的使用方式
函數名字.apply (對象,[參數1,參數2,...])
方法名字.apply (對象,[參數1,參數2,...]) - call 的使用方式
函數名字.call (對象,參數1,參數2,...)
方法名字.call (對象,參數1,參數2,...) - bind 的使用方式:
函數名字.bind (對象,參數1,參數2,...)
函數名字. bind (對象),在調用時再傳遞參數
方法名字.bind (對象,參數1,參數2,...)
方法名字. bind (對象),在調用時再傳遞參數