Javascript深入理解之this * this取决与函数的调用位置,而不是定义的位置,这点很重要 * 1.判断函数是否在new中调用,如果是,this绑定的是新创建的对象 function foo(something) { this.a = something; } var baz = new foo(3); console.log(typeof baz); // => object console.log(baz); // => {'a':3} console.log(baz.a); // => 31 2 3 4 5 6 7 8 1 2 3 4 5 6 7 8 * 上例中:对于baz来说,this只想的是baz本生 * 2.函数是否通过call、apply(显示绑定)或者是硬绑定调用?如果是的话,this绑定的是指定的对象 // 显示绑定--call() function foo() { return this; } var obj = {a: 2}; var baz = foo.call(obj); console.log(typeof baz); // => object console.log(baz); // => {'a': 2} console.log(baz.a); // => 2 1 2 3 4 5 6 7 8 9 10 11 12 1 2 3 4 5 6 7 8 9 10 11 12 * 上例中:通过call(..), 我们可以在调用foo时强制把它的this绑定到obj上 * // 硬绑定--bind() function foo(something) { console.log(something); return this; } var obj = {a: 2}; var baz = foo.bind(obj); // baz为一个新的函数 [Function: bound foo] var bar = baz(4); console.log(bar); // => {'a': 2} // 函数baz为 function baz(something) { console.log(something); return {'a': 2}; }1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 * 上例中:bind(..)会返回一个硬编码的函数,它会把参数设置为this的上下文,并且调用原始的函数 * // API里调用的上下文 function foo(el) { console.log(el, this.id); } var obj = { id: "awe"; } [1, 2, 3].forEach( foo, obj); //此处的foo里面的this指向的是obj // => 1 awe 2 awe 3 awe1 2 3 4 5 6 7 8 9 10 11 1 2 3 4 5 6 7 8 9 10 11 * 上例中:JavaScript和宿主环境中的一些内置函数,都提供了可选的参数,通常被称为上下午,其作用和bind一样,确保你的回掉函数使用指定的this * 3.函数是否在某个上下文对象中调用(隐士绑定)?如果是的话,this绑定的是指定的对象 // 隐式绑定 function foo() { return this.a; } var obj = { a: 2, foo: foo } obj.foo(); // => 21 2 3 4 5 6 7 8 9 10 11 1 2 3 4 5 6 7 8 9 10 11 * 上例中,当函数被当作某个对象的方法调用时,this指向那个对象 * // 隐士丢失 function foo() { console.log(this.a); } var obj = { a: 2, foo: foo } var bar = obj.foo; var a = 'oop'; bar(); // => 'oop'1 2 3 4 5 6 7 8 9 10 11 12 13 1 2 3 4 5 6 7 8 9 10 11 12 13 * 上例中:bar是obj.foo的一个引用,引用的是函数本身,因此此时的bar是一个不带任何修饰的函数,应该实用默认绑定,此时,非严格模式下this指向全局global/window, 严格模式下为undefined* 4.如果前三种情况都不是的话,则为默认绑定,严格模式下,绑定到undefined,非严格模式下指向全局对象 function foo() { console.log(this.a); } var a = 2; foo(); // => 21 2 3 4 5 6 1 2 3 4 5 6 * 上例中:非严格模式下this指向全局global/window, 严格模式下为undefined * 5.this绑定优先级 * new > 硬绑定 > 隐式绑定 * 6.绑定例外 1.箭头函数根据外层作用域来决定this,即箭头函数会继承外层函数调用的this绑定,且箭头函数的绑定无法被修改 2.把null或undefined作为this的绑定对象传入call、apply、bind,这些值调用时会被忽略,实际应用的是默认绑定