#this指向
(一)this的默认绑定
this默认指向window
1。在全局环境下this指向了window
2。函数独立调用,函数内部的this指向了window。或者看函数调用之前挂在了哪一个对象上。
3。被嵌套的函数独立调用时,this默认指向了window。「注意」函数当作对象的方法来调用,this指向该对象。
4。IIFE立即执行函数内部的this指向了window
5。闭包中this中默认指向了window
(二)隐式绑定
看方法前面绑定的对象。
function foo(){
console.log(this.a);
}
var obj = {
a:1,
foo:foo,
obj2:{
a:2,
foo:foo
}
}
obj.foo(); //打印1
obj.obj2.foo(); //打印2
(三)隐式丢失this指向的五种情况
隐式丢失就是指隐式绑定的函数丢失了绑定对象,从而默认绑定到了window,这种情况很容易出错,也很常见。
1。函数别名
var a = 0;
function foo(){
console.log(this.a);
}
var obj = {
a:1,
foo:foo,
}
var bar = obj.foo; //造成了隐式丢失
bar();//相当于window.bar(),输出为0
2。参数传递
var a = 0;
function foo() {
console.log(this.a);
}
function bar(fn) {
fn();
}
var obj = {
a: 1,
foo: foo
}
bar(obj.foo); //this此时指向了window,打印0
obj.foo当作参数传到bar中,有隐式的函数赋值 fn = obj.foo ,只是把foo函数赋值给了fn,但是fn与obj完全没有关系,所以当前foo函数内部的this指向了window。
3.内置函数
setTimeout()和setInterval()第一个参数的回调函数中的this默认指向了window,跟第二种情况是类似的。
4.间接调用
var a = 0;
function foo() {
console.log(this.a);
}
var obj = {
a: 1,
foo: foo
}
var p = {a:2};
obj.foo(); //1
//立即调用的情况
(p.foo = obj.foo)(); //0
//另一种情况
p.foo = obj.foo;
p.foo(); //2
5.其他情况 指向了window的特殊情况
var a = 0;
function foo() {
console.log(this.a);
}
var obj = {
a: 1,
foo: foo
}
(obj.foo = obj.foo)(); //0
(false || obj.foo)(); //0
(1, obj.foo)(); //0
(四)显式绑定
call()—-apply()—bind()把对象绑定到this,叫做显式绑定
var a = 0;
function foo() {
console.log(this.a);
}
var obj = {
a: 1,
foo: foo
}
foo(); //0
foo.call(obj); //1
foo.apply(obj); //1
var fn = foo.bind(obj);
fn(); //1
硬绑定
var a = 0;
function foo() {
console.log(this.a);
}
var obj = {
a: 1,
foo: foo
}
var bar = function(){
foo.call(obj); //this不能再被改变了
}
bar(); //1
setTimeout(bar,2000); //1
bar.call(window); //1
数组的forEach(fn,对象)
var id = ‘window’
function fn(el) {
console.log(el.this.id);
}
var obj = {
id:’fn’
}
[1].forEach(fn);//1 “window”
[1].forEach(fn,obj);//1 “fn”
(五)new绑定
function foo(){
console.log(this);
}
var fn = new foo();
console.log(fn); //指向foo
new关键字来执行函数,相当于构造函数来实例化对象,那么内部的this指向来当前实例化的对象。
function foo(){
console.log(this);
return {
name:”Yingxiu”
}
}
var fn = new foo();
console.log(fn); //指向{name: “Yingxiu”}
使用reurn关键字来返回对象的时候,实例化出的对象就是当前的返回对象。
实例化出来的对象,内部的属性constructor属性指向了当前的构造函数。这是面向对象编程的时候要注意的。
(六)严格模式下的this指向
独立调用的函数内部的this指向了undefined
‘use strict’