您的位置:首页 > Web前端 > JavaScript

JavaScript---浅谈函数this指向之 call()、apply()、bind()方法

2020-01-12 13:56 656 查看

js函数之 call()、apply()、bind()

引言:函数也是对象,所以函数也有属性和方法,例如:构造函数有1个prototype属性。
我们也可以给一个函数对象,添加属性或者方法。

// 先声明一个构造函数
function Person(){ }
console.log(Person.prototype) // Person 这个函数也是一个对象

// 先声明一个构造函数
function Person(){ }
console.log(Person.prototype) // Person 这个函数也是一个对象

// 给Person这个函数添加一个方法
Person.haha = function(){
console.log(haha)
}
// 调用函数方法
Person.haha()

函数内部的this

函数内部有1个关键字this,谁调用这个函数,this就代表谁。

<script>
// 在全局声明一个变量,相当于给 window 对象添加了一个属性
var a = 123; // 等同于 window.a = 123;
// 在全局作用域声明一个函数,相当于给window对象添加了一个方法
// window.fn = function() { }
function fn() {
console.log(this)
console.log(this.a)
}
// 调用fn
fn() // 此时相当于 window.fn() 即,window对象在调用fn
</script>

  • 说道this,就要说一下和this相关的三个方法? 😆
  1. call()方法

注:可以拥有多个参数

call([thisObj[,arg1[,arg2[,argN]]]])

参数说明:
thisObj :要指向的对象
[arg1[,arg2[,argN]]]] :参数列表,参数与参数之间使用逗号隔开

[1] 作用:调用函数,改变函数中的this指向
[2] 参数:第一个,设置函数内部的this指向,其他参数,对应函数的实参
[3] 返回值:call的返回值就是函数的返回值

<script>
function fn(x, y){
console.log(this)
console.log(x + y)
}
var obj = {
name: 'zwt'
}
// fn()
fn.call(obj, 5, 6) // call 调用fn这个函数,此时obj作为第一参数,改变了this的指向。由window指向了obj
</script>

  1. apply()方法

注:最多只能有2个参数

apply([thisObj[,argArray]])
参数说明:
thisObj :要指向的对象
[argArray] :参数列表,要求是一个数组

[1] 作用:改变函数中的this
[2] 参数:只有2个,第一个参数,设置函数中的this指向,第二个参数,数组(元素是函数所需要的参数)
[3] 返回值:apply()的返回值就是函数的返回值

<script>
function fn(x, y){
console.log(this)
console.log(x + y)
}
var obj = {
name: 'zwt'
}
fn.apply(obj, [1, 2])
</script>
  1. bind()方法

注:参数方式跟call类似
[1] 作用:改变函数的this,但是 不会调用函数 而是返回一个新的函数(复制了函数)
[2] 参数:第一个参数设置this的指向,其他参数对应函数的实参
[3] 返回值:bind()返回一个函数

function fn(x, y){
console.log(this)
console.log(x + y)
}
var obj = {
name: 'zwt'
}
var copyFn = fn.bind(obj, 5, 6)
copyFn();
三个方法的场景应用?
  1. call()
  • 第一步,先回顾this指向
<script>
let arr = [1, 4, 7, 9, 6, 12];
// 给数组的原型对象扩展方法,求数组偶数元素和
Array.prototype.getSum = function () {
var sum = 0;
for(let i=0;i<this.length;i++){
if(this[i] % 2 ==0){
sum += this[i]
}
}
return sum
}
console.log(arr.getSum()) // 22 , 当arr调用getSum()时,this 就代表 arr
</script>

第二步,使用call()方法,执行getSum

<script>
let arr = [1, 4, 7, 9, 6, 12];
// 给数组的原型对象扩展方法,求数组偶数元素和
Array.prototype.getSum = function () {
var sum = 0;
for(let i=0;i<this.length;i++){
if(this[i] % 2 ==0){
sum += this[i]
}
}
return sum
}
// console.log(arr.getSum()) // 22 , 当arr调用getSum()时,this 就代表 arr
console.log(Array.prototype.getSum.call(arr)) // 22
</script>

数组的原型对象(Array.prototype)还有拥有其他方法,例如:push()和splice()。
第三步,让伪数组对象(类似数组对象),使用数组方法

var obj = {
0: 100,
1: 10,
2: 11,
3: 20,
length: 4
}
// 使用call方法执行push()方法
Array.prototype.push.call(obj, 30)
Array.prototype.splice.call(obj, 0, 3)
console.log(obj)


2. apply()方法

  • Math.max(1, 3, 5, 8)方法可以求多个数中的最大值。

1、使用Math.max()返回数组元素中的最大值。
思路:把数组展开作为max()的参数,使用apply()方法调用Math.max()方法。

<script>
let arr = [5, 10, 1, 3, 6];
// Math.max(3, 5, 6)
// 使用apply()调用Math.max(),并把数组中的元素作为其参数
console.log(Math.max.apply(Math, arr)) // 10
</script>

2、使用console.log()把数组中的元素都打印出来。
思路:把数组展开作为log()的参数,使用apply()方法调用console.log()方法

<script>
let arr = [5, 10, 1, 3, 6];
// Math.max(3, 5, 6)
// 使用apply()调用console.log(),并把数组中的元素作为其参数
console.log.apply(console, arr)  // 5 10 1 3 6
</script>
  1. bind()方法
  • 定时器的处理函数中的this,默认是window对象。
<script>
setInterval(function() {
console.log(this)
}, 1000); // this指向window
</script>


使用bind()方法后,this指向 obj

<script>
var obj = {
name: 'zwt'
}
setInterval(function() {
console.log(this)
}.bind(obj), 1000); // {name: "zwt"}
</script>
  • 点赞 1
  • 收藏
  • 分享
  • 文章举报
君莫笑·泰 发布了12 篇原创文章 · 获赞 13 · 访问量 1877 私信 关注
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: