前端面试之javascript中的this与call/apply/bind的关系

this
在浏览器里,在全局范围内

  1. this等价于window对象;
  2. 用var声明一个变量和给this或者window添加属性是等价的;
  3. 如果你在声明一个变量的时候没有使用var或者let、const(es6),你就是在给全局的this添加或者改变属性值。

函数中的 this
对于函数中的this的指向问题,有一句话很好用:运行时this永远指向最后调用它的那个对象。

构造函数中的this
所谓构造函数,就是通过这个函数生成一个新对象(object)。当一个函数作为构造器使用时(通过 new 关键字), 它的 this 值绑定到新创建的那个对象。如果没使用 new 关键字, 那么他就只是一个普通的函数, this 将指向 window 对象。

class中的this
在es6中,类,是 JavaScript 应用程序中非常重要的一个部分。类通常包含一个 constructor , this可以指向任何新创建的对象。
不过在作为方法时,如果该方法作为普通函数被调用, this也可以指向任何其他值。与方法一样,类也可能失去对接收器的跟踪。

call、apply和bind中的this
call、apply、bind 被称之为 this 的强绑定,用来改变函数执行时的this指向,目前所有关于它们的运用,都是基于这一点来进行的。

箭头函数中的this
es5中的this要看函数在什么地方调用(即要看运行时),通过谁是最后调用它该函数的对象来判断this指向。但es6的箭头函数中没有 this 绑定,必须通过查找作用域链来决定其值,如果箭头函数被非箭头函数包含,则 this 绑定的是最近一层非箭头函数的 this,否则,this 为 undefined。箭头函数的 this 始终指向函数定义时的 this,而非执行时。

call()、apply()、bind() 都是用来重定义 this 这个对象的!
由于js 中this的指向受函数运行环境的影响,指向经常改变,使得开发变得困难和模糊,所以在封装sdk,写一些复杂函数的时候经常会用到this 指向绑定,以避免出现不必要的问题,call、apply、bind基本都能实现这一功能,现对这三种方法使用总结一下:
call()

function sum(num1, num2){ 
 return num1 + num2; 
}
function callSum(num1, num2){ 
 return sum.call(this, num1, num2); 
} 
console.log(callSum(10,10)); //20

call 方法可以指定this 的指向(即函数执行时所在的的作用域),然后再指定的作用域中,执行函数

call 方法的参数,应该是对象obj,如果参数为空或null,undefind,则默认传参全局对象

call 可以接受多个参数,第一个参数是this 指向的对象,之后的是函数回调所需的入参

call方法的一个应用是调用对象的原生方法。

apply()

function sum(num1, num2){ 
 return num1 + num2; 
} 
function callSum1(num1, num2){ 
 return sum.apply(this, arguments); // 传入 arguments 对象
} 
function callSum2(num1, num2){ 
 return sum.apply(this, [num1, num2]); // 传入数组
} 
console.log(callSum1(10,10)); //20
console.log(callSum2(10,10)); //20

apply 和call 作用类似,也是改变this 指向,然后调用该函数,唯一区别是apply 接收数组作为函数执行时的参数。

**call()的使用和apply()**基本是一样的,不同的是参数的传递,**call()**必须明确的传入每一个参数。

apply方法的第一个参数也是this所要指向的那个对象,如果设为null或undefined,则等同于指定全局对象。

**apply()**方法接受两个参数,一是作用域,二是参数(可以是数组也可以是arguments对象)。

第二个参数则是一个数组,该数组的所有成员依次作为参数,传入原函数。

原函数的参数,在call方法中必须一个个添加,但是在apply方法中,必须以数组形式添加。

bind()
bind 用于将函数体内的this绑定到某个对象,然后返回一个新函数

这个方法会创建一个函数的实例,其this值会被绑定给传入**bind()**函数的值。

var name = "名字";
var person = {name: "小明"};
function sayHello () {
   console.log(this.name + ': hello')
}
var personSay = sayHello.bind(person);
personSay(); *// 小明:hello

总结
call 、 apply 、bind 均能改变this 指向

apply 每次执行产生一个新函数,call、apply 不会

call ,bind 接收多个参数绑定到函数,参数单一传入,apply 接收方式为数组

总结:

在浏览器里,在全局范围内this 指向window对象;

在函数中,this永远指向最后调用他的那个对象;

构造函数中,this指向new出来的那个新的对象;

call、apply、bind中的this被强绑定在指定的那个对象上;

箭头函数中this比较特殊,箭头函数this为父作用域的this,不是调用时的this.要知道前四种方式,都是调用时确定,也就是动态的,而箭头函数的this指向是静态的,声明的时候就确定了下来;
指向最后调用他的那个对象;

构造函数中,this指向new出来的那个新的对象;

call、apply、bind中的this被强绑定在指定的那个对象上;

箭头函数中this比较特殊,箭头函数this为父作用域的this,不是调用时的this.要知道前四种方式,都是调用时确定,也就是动态的,而箭头函数的this指向是静态的,声明的时候就确定了下来;

apply、call、bind都是js给函数内置的一些API,调用他们可以为函数指定this的执行,同时也可以传参。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值