this到底指向什么?
函数在调用时,JavaScript会默认给this绑定一个值
this 绑定规则
this的绑定规则
绑定一:默认绑定
绑定二:隐式绑定
绑定三:显示绑定
绑定四:new绑定
默认绑定
独立的函数调用可以理解成函数没有被绑定到某个对象上进行调用
严格模式,独立调用的函数中的this指向的是undefined
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| function foo () { console.log('foo ', this); };
foo();
const obj = { name: 'why', bar: function () { console.log('bar ', this); }, };
const baz = obj.bar; baz()
|
案例
案例一
1 2 3 4 5
| function () { console.log(this); }
foo()
|
案例二
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| function test1 () { console.log(this); test2(); }
function test2 () { console.log(this); test3(); }
function test3 () { console.log(this); }
test1();
|
案例三
1 2 3 4 5 6 7 8 9 10 11 12 13
| function foo (func) { func() }
const obj = { name: 'why', bar: function () { console.log(this); } }
foo(obj.bar);
|
隐式绑定
通过某个对象进行调用;也就是它的调用位置中,是通过某个对象发起的函数调用
隐式绑定的前提条件
- 必须在调用的对象内部有一个对函数的引用(比如一个属性);
- 如果没有这样的引用,在进行调用时,会报找不到该函数的错误;
- 正是通过这样的引用,间接的将this绑定到这个对象上;
1 2 3 4 5 6 7 8 9 10 11
| function foo () { console.log(this); }
const obj = { bar: foo, }
obj.bar();
|
案例
案例一
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| function foo () { console.log(this); }
const obj = { name: 'obj', foo: foo, }
const obj2 = { name: 'obj2', obj1: obj2, }
obj2.obj1.foo();
|
案例2
1 2 3 4 5 6 7 8 9 10 11
| function foo () { console.log(this); }
const obj1 = { name: 'obj1', foo: foo, }
const bar = obj1.foo; bar();
|
显式绑定
不希望在对象内部包含这个函数的引用,同时又希望在这个对象上进行强制调用;可以使用显式绑定
call和apply方法
- 第一个参数是相同的,要求传入一个对象
- 这个对象的作用就是给this准备的
- 在调用这个函数时,会将this绑定到这个传入的对象上
- 后面的参数;apply为数组,call为参数列表
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| function foo (name, age, height) { console.log('foo 函数被调用 ', this); console.log('打印参数 ', name, age, height); }
foo.call('call', 'james', 35, 205);
|
bind 的显示绑定
- 如果我们希望一个函数总是显式的绑定到一个对象上,可以使用 bind 方法;bind()方法创建一个新的绑定函数(bound function, BF)
- 绑定函数是一个exotic function object(怪异函数对象,ECMAScript 2015 中的术语)
- 在bind() 被调用时,这个新函数的this被指定为bind() 的第一个参数,而其余参数将作为新函数的参数,供调用时使用
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| function foo (name, age, height) { console.log('foo ', this); }
const obj = { 'name': 'why' };
const bar = foo.bind(obj); bar();
const test = foo.bind(obj, 'kobe', 30, 198) test()
|
new绑定
JavaScript中的函数可以当做一个类的构造函数来使用,也就是使用new关键字
使用new关键字调用函数执行的操作
- 创建新的空对象;
- 新对象会被执行prototype连接;
- 新对象会绑定到函数调用的this上(this绑定在这个步骤完成);
- 没有显示返回非空对象时,默认返回这个对象;
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| function foo () { this.name = 'why'; console.log(this); }
new foo();
function Person (name) { console.log(this); this.name = name; }
const p = new Person('why'); console.log(p);
|
内置函数的调用绑定