JavaScript的this

this

首先,说下this的两个常见误区

指向自身?

因为this的从英文的角度上,很容易给人自身感觉,导致出this指向函数自身的想法。

function foo(){
	var a = 4;
	console.log(this.a); // undefined
	console.log(this.b); // undefined
	console.log(foo.b);; // 1
}

foo.b = 1;
foo()

很明显,this并不是指向函数自身的,this.bfoo.b并不是同一个

this指向与函数的作用域有关?

function foo(){
	var a = 4;

	function baz(){
		console.log(a); // 4
		console.log(this.a); // undefined
	}

	baz()
}

foo()

试图用作用域链的方法查找a,然而this并不买账。

那么接下来开始真正介绍this

this的绑定规则

this的绑定要判断用了什么规则,总共有四条。

默认绑定

默认绑定就是this指向window

var a = 4;

function foo(){
	this.bar();
}

function bar() {
	console.log(this.a) // 4
	console.log(window.a) // 4
}

foo()

正是因为this指向window,而bar和a又刚好作为window的属性,所以可以访问

当其他规则无法适用时,就会绑定到window

隐式绑定

如果函数作为某个对象的属性,那么this就会指向这个对象

var a = 4;

function foo(){
	this.bar(); // 2
	console.log(this.a); // 1
}

var obj = {
	a: 1,
	bar: function(){
		console.log(2)
	},
	foo
}

obj.foo()

从这也可以看出,隐式绑定的优先级要高于默认绑定

丢失绑定

隐式绑定如果操作不当,会导致绑定丢失

var a = 4;

function foo(){
	//this.bar(); 报错,this指向window,但window没有bar函数
	console.log(this.a); // 4
}

var obj = {
	a: 1,
	bar: function(){
		console.log(2)
	},
	foo
}

var baz = obj.foo;
baz()

这种情况下,将对象里的函数赋值给一个变量baz,所以baz是foo的引用,但是它引用的是foo本身,并不是obj里的foo,所以这时候的this就指向了window

显示绑定

通过call()apply()来改变this的指向

var a = 4;

function foo(){
	console.log(this.a); // 1
}

var obj = {
	a: 1
}

var obj1 = {
	a: 2
}

function baz() {
	foo.call(obj1); // 2
}

function bar(){
	foo.call(obj)
}
bar(); // 1
baz()
foo(); // 4


foo.call(this要绑定到的对象),通过this.call就可以指定this的对象了,不过这里要注意的是,并不是绑定后,foo的this就到指定的对象了,只有在执行这段代码foo.call()的时候,this才发生改变,最后一行代码,单独调用了foo,this依然指向window。

new绑定

使用new来调用函数,或者说发生构造函数调用时,会自动执行下面的操作

  • 创建一个全新的对象
  • 这个新对象会被执行[[Prototype]]连接
  • 这个新对象会绑定到函数调用的this
  • 如果函数没有返回其他对象,那么new表达式中的函数调用会自动返回这个新对象
function foo(a){
	this.a  = a;
	
	this.baz = function(){
		console.log('hellow'+ a)
	}
}
var bar = new foo(2);
console.log(bar.a)
bar.baz();

这时this就指向了new出来的实例了

posted @ 2019-12-30 15:24  司徒炼  阅读(166)  评论(0编辑  收藏  举报