this的默认绑定
- 全局环境下的this指向window
- 函数独立调用,函数内部的this指向window
function fn(){
console.log(this);//window
}
var a = 0;
var obj = {
a:2,
foo:function(){
function test(){
//window调用的test函数 所以指向的是window
console.log(this.a);//0
}
}
}
obj.foo();
3.被嵌套的函数独立调用时,this默认指向了window
var a = 0;
var obj = {
a:2,
foo:function(){
//函数当做对象的方法来调用 this指向obj
var that = this;
function test(){
console.log(that.a);2
}
}
}
obj.foo();
- IIFE 自执行函数this指向window(隐式绑定)
var a = 0;
function foo(){
console.log(this.a);//2
(function test(){
console.log(this.a);//0
})();
}
var obj = {
a:2,
foo:foo
}
- 闭包中this指向window 原理与IIFE一致
绑定丢失
- 隐式绑定
var a = 10;
function foo(){
console.log(this.a);//10
}
var obj = {
a:2,
foo:foo
}
var bar = obj.foo;
bar();
//这时候的this指向的是window 因为bar()=window.bar();
小结:看哪个对象调用的这个函数 那么这个函数指向的就是这个对象 如果上面代码的后两行换成
var bar = obj.foo();
bar;
那么foo函数指向的是obj对象 打印的是obj里的a 故为2
2. 参数传递
var a = 10;
function foo(){
console.log(this.a);//10
}
var obj = {
a:2,
foo:foo
}
function bar(fn){
fn();
}
bar(obj.foo);
//把obj.foo当做参数传递到bar函数中,其实就是把foo函数丢给了bar去调用,
//所以this指向的是bar
- 内置函数
var a = 10;
function foo() {
console.log(this.a);//10
}
var obj = {
a: 1,
foo: foo
}
setTimeout(obj.foo, 1000);
//原理与上面一致
- 间接调用
function foo() {
console.log(this.a);
}
var a = 10;
var obj = {
a: 2,
foo: foo
}
var p = { a: 4 }
obj.foo();//2
//将obj.foo函数对象赋值给p.foo函数然后立即执行。
//相当于仅仅是foo()函数的立即调用 默认指向window
(p.foo = obj.foo)();//10 立即执行的this都指向window
//将obj.foo赋值给p.foo。函数,之后p.foo()函数再执行,
//其实是属于p对象的方法的指向,this指向当前的p对象
p.foo = obj.foo;
p.foo();//4
显示绑定
var a = 10;
function foo() {
console.log(this.a);
}
var obj = {
a: 1
}
foo();//10
foo.call(obj);//1
foo.apply(obj);//1
var fn = foo.bind(obj);
fn();//1
- 硬绑定
var a = 10;
function foo() {
console.log(this.a);
}
var obj = {
a: 2
}
var bar = function () {
foo.call(obj);
}
bar();//2
setTimeout(bar, 1000);//2
bar.call(window);//2
- 回调函数
var id = 'window';
function fn(el) {
console.log(el, this.id);
}
var obj = {
id: 'fn'
}
var arr = [1, 2, 3];
arr.forEach(fn);//window
arr.forErch(fn, obj);//obj
new绑定
function fn() {
//如果是new关键字来执行函数,相当于构造函数来实例化对象,
//那么内部的this指向当前的实例化对象
console.log(this);
}
var fn = new fn();
fn;
function fn2() {
console.log(this);//fn2
//是用return返回对象的时候,实例化出来的对象是当前的返回对象
return {
name: 'qaq'
}
}
var fn2 = new fn2();
console.log(fn2);//obj对象
var person = {
fav: function () {
return this;
}
}
var p = new person.fav();
console.log(p);//fav {}
//实例化出来的对象内部属性constructor属性指向当前的构造函数
console.log(p.constructor === person.fav);//true
严格模式下的this指向
- 严格模式下,独立调用的函数内部this指向undefined
- 严格模式下,函数apply()和call()内部的this始终是它们的第一个参数