每一个函数执行都会产生一个this指向,this的指向可能会相等,但不代表this相同。本身是不相同的。
函数执行才会产生this指向,函数不执行,this是没有任何意义的。每一个this实际上都代表着一个函数的执行
1.默认绑定规则
在全局当中指向window
函数的独立调用指向window
<script>
console.log(this)
//指向window
//函数的独立调用
function test(){
console.log(this)
//指向window
}
test();
</script>
2.隐式绑定规则
谁调用就指向谁
通过对象的属性的方法来调用,this指向节点对象
<script>
var a=0;
var obj={
a:2,
foo:function(){
console.log(this==obj);
function test(){
//与上一个this是不同的this,属于不同的函数
//这里的this指向取决于调用方法
conlose.log(this)
}
//直接看调用的方式,独立调用就是指向window
test();
//函数立即执行,this也是指向window
(function(){
console.log(this)
})()
}
obj.foo();
</script>
闭包:当函数执行的时候,导致函数被定义,并抛出
当函数产生闭包的时候,函数的this指向window
<script>
var a=0;
var obj={
a:2,
foo:function(){
console.log(this==obj);
function test(){
conlose.log(this)
}
teturn test;
obj.foo()();
//obj.foo()执行完毕就相当于test,test()独立调用window
</script>
隐式丢失 :当方法被赋值的时候会产生
上面提过this指向是在函数调用大的时候产生的,在限免这段函数中,函数的调用在最后面,bar()。这时候obj.foo没有调用,即obj.foo就是function,bar嗲用的时候就是调用function,所以bar就变成了独立调用。
var bar=obj.foo;与var bar=foo;是相同的
<script>
var a=0;
function foo(){
console.log(this);
}
var obj={
a:2,
foo:foo
}
obj.foo();//this指向obj
var bar=obj.foo;
bar();//指向window
</script>
参数赋值的情况
同样的obj.foo就是foo();则fn()就是foo()这个函数,fn()是独立调用,那么此时foo()就是独立调用,this的指向就是window。
这里的this指向是有fn()的执行方式决定的,所以父函数是有能力决定子函数的this指向的。
<script>
var a=0;
function foo(){
console.log(this);
}
function bar(fn){
fn();
}
var obj={
a=2,
foo:foo
}
//预编译的过程中,实参被赋值为形参(值的拷贝的过程,浅拷贝)
bar(obj.foo);
</script>
3.显示绑定规则
call(), apply(), bind()
用来更改this指向
区别:传参的方式不同,call直接零散的传参,apply以数组的形式进行传参,bind返回一个新的函数,本身并不执行,在新函数执行的时候传入参数。
js中一切皆对象,所以在改变this指向的时候,传入数字就指向number,如果传入undefined和null就会导致绑定失败,则此时的this指向window
<script>
var a=0;
function foo(a,b,c){
console.log(this);
}
var obj={
a:2,
foo:foo
}
obj.foo();//this指向obj
var bar=obj.foo;
bar();//指向window
obj.foo(1,2,3)
bar.call(obj,1,2,3);
bar.apply(obj,[1,2,3]);
bar.bind(obj)(1,2,3);
</script>
4.new 绑定
这里的this其实是函数在实例化对象之后所执行的结果,this指向实例化对象
如果return返回的值为引用值,this的指向就会被更改,那么此时的this指向就不会指向实力之后的对象。
<script>
function Person(){
this.a=1;
//return this;
//return 1;
//return的值为引用值
return{};
}
var person=new Person();
console.log(person);
</script>
5.this指向的优先级
new绑定>显示绑定>隐式绑定>默认绑定。