你不知道this指向,以及如何改变this指向

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(); // 42
obj1的属性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 ); // 5
apply和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
 

 


  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值