总结
1.默认绑定规则 console.log(this===window)//true
2.
有优先级4>3>2>1,隐式绑定偷偷绑定,编译器自动绑定
独立调用、对象调用、显示绑定调用
1.默认绑定规则
1.默认绑定规则:
console.log(this===window)//true
console.log({}==={})//false
函数独立调用
function test(){
console.log(this=== window)
}
test()
true,函数没有new,this指向window,其实是window.test()的简写,其实也可以看作window调用
独立调用就指向window:与方式有关,有地方无关,只要独立调用就指向window
2.隐式绑定规则
var a=0;
var obj={
a:2,
foo:function() {
console.log(this)
}
}
obj.foo()
obj 函数内部的this指向,obj调用函数,可以看作obj.foo再执行
obj调用函数执行,函数内的this指向obj,指向调用者
var a=0;
var obj={
a:2,
foo:function() {
console.log(this)//obj
function test(){
console.log(this)//window
}
test()
}
}
obj.foo()
预编译会有AO、GO,AO、GO里面有this,this在预编译时确定,每个函数中都会有this指向问题,因为this存在于AO、GO中,所以只有在函数执行才有this指向问题,不执行没有
因为它俩是不同函数,有不同的AO,所以this是不一样的,但存在指向同一个地址的可能性
obj是对象,不是函数,不能执行,没有AO也就没有this指向,obj就是存储数据的,属性和方法都是数据
function方法存储代码块,片段
test()就是独立调用,独立调用就指向window,看的是调用的方式,不是在哪调用
var a = 0;
var obj = {
a: 2,
foo: function () {
console.log(this);//obj
// function test(){
// console.log(this)
// }
// test()
; (function () {
console.log(this)//window
})();
}
}
obj.foo();
同样是window,因为立即执行函数,相当于声明函数,再执行,和上面的声明test再执行意思是一样的
var a = 0;
var obj = {
a: 2,
foo: function () {
console.log(this);
// function test(){
// console.log(this)
// }
// test()
// ; (function () {
// console.log(this)
// })();
function test(){
console.log(this);
}
return test;
//当函数执行的时候,导致函数被定义,并抛出
}
}
obj.foo()();
// var a=obj.foo();
// a()
还是window,obj.foo()相当于test函数,obj.foo()()相当于test()函数执行,这是独立调用,this是window
变量赋值:隐式丢失
var a=0;
function foo(){
console.log(this);
}
var obj = {
a:2,
foo:foo
/* 相当于foo:function foo(){...}
属性foo指向函数foo,指向可以看作复制一份代码到此处*/
}
obj.foo();//obj
//隐式丢失
var bar=obj.foo;
bar();//window
把bar指向方法foo但没有执行,bar()再执行,相当于foo()
当方法被赋值时会产生隐式丢失
参数赋值的情况
var a = 0;
function foo() {
console.log(this);
}
function bar(fn) {
fn()
}
var obj = {
a: 2,
foo: foo
}
bar(obj.foo)//window
obj.foo相当于函数foo(),bar(foo)相当于func bar(){ foo() },独立调用
var a = 0;
function foo() {
console.log(this);
}
function bar(fn) {
// console.log(this);
fn(obj)
// new fn();
// fn.bind(obj)();
}
var arr=[1,2,3]
arr.forEach(function(item,idx,arr) {
})
//父函数是有能力决定 子函数的this指向的;
var obj = {
a: 2,
foo: foo
}
//预编译的过程中,实参被赋值为形参;(值的拷贝的过程,前拷贝);
bar(obj.foo)//window
父函数是有能力决定 子函数的this指向的;
比如fn.call,arr数组的方法forEach的参数中有this的参数,可以指定forEach参数函数的this指向
var arr=[1,2,3];
arr.forEach(function(item,idx,arr){
console.log(this)
})
arr.sort(function(a,b){
console.log(this);
return a-b;
})
// setInterval(function() {
// console.log(this)
// })
3.显示绑定
call等
undefined、null没有包装类,绑定必须是对象,绑定失败,执行默认绑定方式
4.new绑定
function Person(){
var this={};
this.a=1;
return this;
}
var person=new Person();
this指向实例对象,new默认返回this,并且隐式把this从指向window变成指向实例对象
var person=new Person();
console.log(person)
console.log(typeof person)
因为返回的是this={},所以typeof是object
call优先级更大
返回{}object,返回引用值会替代this引用值
var name='222';
var a={
name :'111',
say:function() {
console.log(this.name)
}
}
var fun=a.say;
/*相当于var fun=function(){console.log(this.name)}*/
fun();//222 独立调用 this指向window
a.say();//111 对象调用
222 111