前言
相信很多人都对JavaScript中的this指向问题一知半解,所以今天就来详细看看它到底是怎么判断的。
一. 先看几道题
var length = 10;
function fn() {
console.log(this.length);
}
var obj = {
length: 5,
method: function(fn) {
fn();
arguments[0]();
}
};
obj.method(fn, 1); // 10 2
var name = 'window';
function f1() {
var name = 'f1';
return function f2() {
var name = 'f2';
console.log(this.name);
}
}
var foo = f1();
var bar = {
name: 'bar',
foo: foo
};
foo(); // window
bar.foo(); // bar
var name = 'window';
var bar = {
name: 'bar',
foo: function () {
var self = this;
console.log(this.name);
console.log(self.name);
(function () {
console.log(this.name);
console.log(self.name);
})()
}
};
bar.foo(); // bar bar window bar
var name = 'window';
function f1() {
var name = 'f1';
return () => {
var name = 'f2';
console.log(this.name);
}
}
var foo = f1();
var bar = {
name: 'bar',
foo: foo
};
foo(); // window
bar.foo(); // window
二. this绑定规则
1.绑定默认
- 当其他规则无法应用时将采用默人绑定
- 默认绑定将会绑定到全局对象
- 严格模式(strict mode)下不能讲全局对象用于默认绑定
function foo() {
console.log(this === window);
}
foo() // true
function bar() {
"use strict";
console.log(this === window);
console.log(this);
}
bar() // false undefined
2.隐式绑定
如果函数引用有上下文对象时,this将会绑定到这个对象。椎确来说是函数调用时是否有引用上下文对象。
var name = 'window';
function foo() {
console.log(this.name);
}
var obj = {
name: 'obj',
foo: foo
};
obj.foo(); // obj 隐式绑定,上下文对象obj
var bar = obj.foo;
bar(); // window 无上下文对象
3.显示绑定
这也是常用的的方式:call、apply、bind 就不一一举例了。
function foo() {
console.log(this.name);
}
var obj = {
name: 'obj'
};
foo.call(obj) // obj
4.new绑定
var a;
function foo(a) {
this.a = a
}
var bar = new foo(2);
console.log(a); //undefined
console.log(bar.a); // 2 this了bar
三.优先级
var a;
function foo(a) {
this.a = a;
}
var obj = {
foo: foo
};
var obj2 = {};
console.log(a); // undefined
obj.foo(1);
console.log(obj.a); // 1
obj.foo.call(obj2, 2);
console.log(obj2.a); // 2
var baz = obj.foo.bind(obj2);
var bar = new baz(3);
console.log(bar.a); // 3
从上面的代码可以看出优先级从高到低依次是:new绑定、显示绑定、隐式绑定、默认绑定。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。