• 在全局作用域下this的指向就是window,
let a = 10
console.log(this.a) // 不管是非严格模式还是严格模式都是this
  • 函数执行的时候,看前面有没有.如果有点.前面是谁,函数执行的时候,里面的this就是谁,如果没有点.里面的this就是window(非严格模式下),在严格模式下就是undefined
let obj ={
	name:10
}
function fn(){
	console.log(this) 
}
obj.fn() // this输出的是obj
  • 给元素绑定事件的时候,当事件触发里面的this就是当前绑定的元素
<div id=ele> ele </div>

let ele.onclick = function(){
	console.log(this) // 则是被绑定的元素
}
  • 自执行函数的this非严格模式下window,在严格模式下就是undefined
(function(){
	console.log(this)
})()
  • 回调函数里面this是window
function fn(callback){
	console.log(this)
	callback()
}
fn(function(){
	console.log(this)
})
  • 通过类创造的实例,构造函数中的this指的就是当前的实例
function fn(){
	this.name = "lili",
	this.age = 20
}
var f1 = new fn() //  当前的this就是f1的实例
var f2 = new fn() //  当前的this就是f2的实例

通过call/apply/bind可以更改this的指向

call

function fn(){
	console.log(this)
}
let obj = {
	name:"lili"
}
fn.call(obj) // 此时this就被指向obj
  • 构造函数里面的this就是指向当前的实例,通过this添加的属性名和都属性值都是跟当前的实例添加的
function fn(sum){
	this.num = 10
	this.name = "小铭"
	this.age  = sum
	}
let f1 = new fn(10) // f1是fn的当前实例
// 内置call实现的原理
~ function (){
function MyCall(context,...params){
	//context = null ? context = window.null;
	if(!/^(Object|function)$/.test(typeof context)).context = Object(context);
	let _this = this,
	    key = Symbol('KEY'),
	    result;
	    context[key] = _this;
	    result = context[key];
	    return result;
}
	Function.prototype.MyCall = MyCall;
}();

call和apply各自的定义:

  • apply:调用一个对象的一个方法,用另一个对象替换当前对象。例如:B.apply(A, arguments);即A对象应用B对象的方法。

  • call:调用一个对象的一个方法,用另一个对象替换当前对象。例如:B.call(A, args1,args2);即A对象调用B对象的方法。

call和apply共同之处:

  • 都可以用来代替另一个对象调用一个方法,将一个函数的对象上下文从初始的上下文改变为由thisObj指定的新对象”。

call和apply不同之处:

  • apply:最多只能有两个参数——新this对象和一个数组argArray。如果给该方法传递多个参数,则把参数都写进这个数组里面,当然,即使只有一个参数,也要写进数组里。如果argArray不是一个有效的数组或arguments对象,那么将导致一个TypeError。如果没有提供argArray和thisObj任何一个参数,那么Global对象将被用作thisObj,并且无法被传递任何参数。

  • call:它可以接受多个参数,第一个参数与apply一样,后面则是一串参数列表。这个方法主要用在js对象各方法相互调用的时候,使当前this实例指针保持一致,或者在特殊情况下需要改变this指针。如果没有提供thisObj参数,那么 Global 对象被用作thisObj。

实际上,apply和call的功能是一样的,只是传入的参数列表形式不同。

bind

function MyBind(context,...params){
	let _this = this;
	return function proxy(...args){
		params = params.concat(agrs);
		return _this.call(context,...params)
	}
}
  • bind和call/apply的最大区别就是他不是立即执行而call/apply它时立即就执行了
  • bind可以用于点击事件,触发点击事件后才会执行。

最后声明一下:箭头函数中没有this,也没有arguments,但是在箭头函数中用this,会向上级作用域链去找

Q.E.D.


学而不厌 不耻下问