this
在浏览器里,在全局范围内
- this等价于window对象;
- 用var声明一个变量和给this或者window添加属性是等价的;
- 如果你在声明一个变量的时候没有使用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的执行,同时也可以传参。