学习记录_0903

this

https://juejin.im/post/6844903496253177863

this 的指向

this永远指向最后调用它的那个对象

例1:

var name = "windowsName"
function a() {
    
    
	var name = "Cherry"
	console.log(this.name)        //   windowsName
	console.log("inner:" + this)   //   inner:Window
}  
a()
console.log("outer:" + this)     //   outer:Window

最后调用 a 的地方 a(),前面没有调用的对象 那么就是全局对象window,相当于是window.a()。(如果使用严格模式,全局对象是 undefined,会报错)

例2:

var name = "windowsName"
var a = {
    
    
	name:"Cherry",
	fn:function() {
    
    
		console.log(this.name)	// Cherry
	}
}
a.fn()

函数fn是对象a调用的,所以打印的值就是a中的name的值。

例3:

var name = "windowsName"
var a = {
    
    
	name:"Cherry",
	fn:function() {
    
    
		console.log(this.name)	// Cherry
	}
}
window.a.fn()

这里打印Cherry的原因也是因为“this永远指向最后调用它的那个对象”最后调用他的对象仍然是对象a

例4

var name = "windowsName"
var a = {
    
    
	// name:"Cherry",
	fn:function() {
    
    
		console.log(this.name)	// undefined
	}
}
window.a.fn()

调用fn的是a对象,也就是说fn的内部的this是对象a,而对象a中并没有对name进行定义,就算a中没有name这个属性,也不会继续向上一个对象寻找 this.name,而是直接输出 undefined。

例5

var name = "windowsName"
var a = {
    
    
	name:null,
	fn:function() {
    
    
		console.log(this.name)	// windowsName
	}
}
var f = a.fn
fn()

这里虽然将a对象的fn方法赋值给变量f了,但是没有调用,所以fn()最后仍然是被window调用的。所以this的指向也就是window。

例5

var name = "windowsName"
var a = {
    
    
	var name = 'Cherry'
	innerFunction()
	function innerFunction() {
    
    
		console.log(this.name)	// windowsName
	}
}
fn()

改变 this 的指向

  • 使用es6的箭头函数
  • 在函数内部使用 _this = this
  • 使用 apply、call、bind
  • new 一个实例化对象

例7:

var name = "windowsName"
var a = {
    
    
	name:"Cherry"
	func1:function() {
    
    
		console.log(this.name)	
	}
	func2:function() {
    
    
		setTimeout( function() {
    
    
			this.func1()
		},100)	
	}
}
a.func2()    // this.func1 is not a function

在不使用箭头函数情况下是会报错的,因为最后调用 setTimeout 的对象是 window,但是在 window 中并没有 func1 函数

箭头函数

箭头函数的this始终指向函数定义时的this,而非执行时。箭头函数中没有this绑定,必须通过查找作用域链来决定其值,如果箭头函数被非箭头函数包含,则this绑定在最近一层非箭头函数的this,否则,this为undefined

例8:

var name = "windowsName"
var a = {
    
    
	name:"Cherry"
	
	func1:function() {
    
    
		console.log(this.name)	
	}
	
	func2:function() {
    
    
		setTimeout( () => {
    
    
			this.func1()
		},100)	
	}
}
a.func2()    // Cherry

在函数内部使用 _this = this

先将调用这个函数的对象保存在变量 _this 中,然后在这个函数中都使用 _this,这样 _this 就不会改变了

例9:

var name = "windowsName"
var a = {
    
    
	name:"Cherry"
	
	func1:function() {
    
    
		console.log(this.name)	
	}
	
	func2:function() {
    
    
		var _this = this
		setTimeout( function() {
    
    
			_this.func1()
		},100)	
	}
}
a.func2()    // Cherry

在 func2 中先设置 _this = this,这里的this 是调用func2 的对象a,为了防止在 func2 中的 setTimeout 被 window 调用而导致在 setTimeout 中的 this 为 window。将this(指向变量a)赋值给一个变量 _this,这样在 func2中使用_this 就指向对象a了。

使用apply、call、bind
例 10:

//  使用apply
var a = {
    
    
	name:"Cherry"
	
	func1:function() {
    
    
		console.log(this.name)	
	}
	
	func2:function() {
    
    
		setTimeout( function() {
    
    
			this.func1()
		}.apply(a),100)	
	}
}
a.func2()    // Cherry

例 11:

//  使用call
var a = {
    
    
	name:"Cherry"
	
	func1:function() {
    
    
		console.log(this.name)	
	}
	
	func2:function() {
    
    
		setTimeout( function() {
    
    
			this.func1()
		}.call(a),100)	
	}
}
a.func2()    // Cherry

例 12:

//  使用bind
var a = {
    
    
	name:"Cherry"
	
	func1:function() {
    
    
		console.log(this.name)	
	}
	
	func2:function() {
    
    
		setTimeout( function() {
    
    
			this.func1()
		}.bind(a),100)	
	}
}
a.func2()    // Cherry

apply和call的区别

基本类似 传参不同 call方法接收的是若干个参数列表,而apply接受的是一个包含多个参数的数组

例 13:

var a = {
    
    
	name:"Cherry"
	fn:function(a,b){
    
    
		console.log(a+b)
	}
}
var b = a.fn
b.apply(a,[1,2])           // 3

例 14:

var a = {
    
    
	name:"Cherry"
	fn:function(a,b){
    
    
		console.log(a+b)
	}
}
var b = a.fn
b.call(a,1,2)           // 3

bind和apply、call的区别

bind()方法创建一个新的函数,当被调用时,将其this关键字设置为提供的值,在调用新函数时,在任何提供之前提供一个给定的参数序列。所以bind是创建一个新的函数,必须手动调用。

var a = {
    
    
	name:"Cherry"
	fn:function(a,b){
    
    
		console.log(a+b)
	}
}
var b = a.fn
b.bind(a,1,2)()           // 3

猜你喜欢

转载自blog.csdn.net/vigorZ/article/details/108404216
今日推荐