function foo() { console.log( this.a ); } var a = 2; foo(); // 2 -----------------------------------------------++++--------------------------------------------------------------
function foo() { "use strict"; console.log( this.a ); } var a = 2; foo(); // TypeError: `this` is `undefined`
严格模式下会报错,不严格模式this 指向的是全局变量
再来看一组
function foo() {
console.log( this.a );
}
var a = 2; (function(){ "use strict"; foo(); // 2 })();
故意将严格的模式和非严格的模式混合在一起通常是不受欢迎的。您的整个程序应该是严格的或不严格的。然而,
有时您包含的第三方库具有不同于您自己的代码的严格性,因此必须小心处理这些微妙的兼容性细节
function foo() { console.log( this.a ); } var obj = { a: 2, foo: foo }; obj.foo(); // 2
对象obj的属性有foo,注意仅仅是一个名字,让obj的foo属性,foo函数的指针指向foo
function foo() { console.log( this.a ); } var obj2 = { a: 42, foo: foo }; var obj1 = { a: 2, obj2: obj2 }; obj1.obj2.foo(); // 42obj1的属性obj2,obj2的值为对象obj2,obj2的两个属性 a,foo,因此foo函数的this指向是调用它的对象,它的对象为obj2,
function foo() { console.log( this.a ); } var obj = { a: 2, foo: foo }; var bar = obj.foo; // function reference/alias! var a = "oops, global"; // `a` also property on global object bar(); // "oops, global"bar的值为obj.foo,注意bar为全局对象,obj.foo==foo;所以调用bar();this的指向为window ,所以bar()运行结果为
oops,global
function foo() { console.log( this.a ); } function doFoo(fn) { fn(); } var obj = { a: 2, foo: foo }; var a = "oops, global"; // `a` also property on global object doFoo( obj.foo ); // "oops, global"首先,我们可以看到obj.foo指向的指针foo函数,如果obj.foo()调用结果为2,但是注意,发现是函数doFoo调用,但是它的
实参是obj.foo==foo相当于把foo函数的名字传递进去,在doFoo函数里边调用
(实际上this的最终指向的是那个调用它的对象),是doFoo,调用他,doFoo的this指的是window,因此结果为
"oops,global"
function foo() { console.log( this.a ); } var obj = { a: 2, foo: foo }; var a = "oops, global"; // `a` also property on global object setTimeout( obj.foo, 100 ); // "oops, global"同样道理,setTimeout 为全局变量,所以结果为 "oops, global"
function foo() { console.log( this.a ); } var obj = { a: 2 }; foo.call( obj ); // 2 call 和 apply 都是为了改变函数体内部 this 的指向。 call方法与apply方法的第一个参数是一样的,只不过第二个参数是一个参数列表 此时foo方法将被obj引用 ,this指向了obj
function foo() { console.log( this.a ); } var obj = { a: 2 }; var bar = function() { foo.call( obj ); }; bar(); // 2 setTimeout( bar, 100 ); // 2 // `bar` hard binds `foo`'s `this` to `obj` // so that it cannot be overriden bar.call( window ); // 2 不管如何改变bar中this的指向,foo.call引用obj,所以他的值都不会变
function foo(something) { console.log( this.a, something ); return this.a + something; } var obj = { a: 2 }; var bar = function() { return foo.apply( obj, arguments ); }; var b = bar( 3 ); // 2 3 console.log( b ); // 5apply和call一样,不过apply第二个参数需要是一个数组,或者类数组
function foo(el) { console.log( el, this.id ); } var obj = { id: "awesome" }; // use `obj` as `this` for `foo(..)` calls [1, 2, 3].forEach( foo, obj ); // 1 awesome 2 awesome 3 awesome forEach的第二个参数就是this的指向
function foo(a) { this.a = a; } var bar = new foo( 2 ); console.log( bar.a ); // 2
通过调用foo(..),在它前面加上new,我们构造了一个新对象,并将这个新对象设置为foo(..)调用的对象。
所以新的是函数调用的最终方式。
我们将调用这个新的绑定。
function foo(something) { this.a = something; } var obj1 = {}; var bar = foo.bind( obj1 ); bar( 2 ); console.log( obj1.a ); // 2 var baz = new bar( 3 ); console.log( obj1.a ); // 2 console.log( baz.a ); // 3