关于js中的this的指向问题(一)

本文参考 你不知道的javascript第二章 this全面解析

首先明确一点。。。每个函数的this是在调用时被绑定的,完全取决于函数的调用位置

接下来看怎么辨别调用位置,先来看几个例子

function baz() {
// 当前调用栈是:baz
// 因此,当前调用位置是全局作用域
console.log( "baz" );
bar(); // <-- bar的调用位置
}
function bar() {
// 当前调用栈是baz -> bar
// 因此,当前调用位置在baz中
console.log( "bar" );
foo(); // <-- foo的调用位置
}
function foo() {
// 当前调用栈是baz -> bar -> foo
// 因此,当前调用位置在bar中
console.log( "foo" );
}
baz(); // <-- baz的调用位置

看明白调用位置了吗?

在绑定规则上记住默认绑定就是其他绑定规则用不到就用默认规则。记住以下几点
1.默认绑定

function foo() {
console.log( this.a );
}
var a = 2;
foo(); // 2  这里this指向全局(在非严格模式下,因为在严格模式下this不指向window,而是指向undefined

2.隐式绑定
隐式绑定时,我们必须在一个对象内部包含一个指向函数的属
性,并通过这个属性间接引用函数,从而把this间接(隐式)绑定到这个对象上。

function foo() {
console.log( this.a );
}
var obj = {
a: 2,
foo: foo
};
obj.foo(); // 2  此时this指向obj对象

在对象属性引用链中只有最顶层或者说最后一层会影响调用位置

function foo() {
console.log( this.a );
}
var obj2 = {
a: 42,
foo: foo
};
var obj1 = {
a: 2,
obj2: obj2
};
obj1.obj2.foo(); // 42此时this指向obj2

比较特殊的隐式绑定(名叫隐式丢失)
1).

function foo() {
console.log( this.a );
}
var obj = {
a: 2,
foo: foo
};
var bar = obj.foo; // **函数别名!**
var a = "oops, global"; // a是全局对象的属性
bar(); // "oops, global"   对于别名的是使用了默认绑定

2)..参数传递其实就是一种隐式赋值

function foo() {
console.log( this.a );
}
function doFoo(fn) {
// fn其实引用的是foo
fn(); // <-- 调用位置!
}
var obj = {
a: 2,
foo: foo
};
var a = "oops, global"; // a是全局对象的属性
doFoo( obj.foo ); // "oops, global"  

3).把函数传入语言内置的函数而不是传入你自己声明的函数

function foo() {
console.log( this.a );
}
var obj = {
a: 2,
foo: foo
};
var a = "oops, global"; // a是全局对象的属性
setTimeout( obj.foo, 100 ); // "oops, global"

3.显示绑定

不想在对象内部包含函数引用,而想在某个对象上强制调用函数可以使用函数的call(..)和apply(..)方法
它们的第一个参数是一个对象,它们会把这个对象绑定到this,接着在调用函数时指定这个this。因为你可以直接指定this的绑定对象,因此我们称之为显式绑定。

function foo() {
console.log( this.a );
}
var obj = {
a:2
};
foo.call( obj ); // 2   通过foo.call(..),我们可以在调用foo时强制把它的this绑定到obj上

//如果你传入了一个原始值(字符串类型、布尔类型或者数字类型)来当作this的绑定对象,这个原
//始值会被转换成它的对象形式(也就是new String(..)、new Boolean(..)或者new Number(..))。这通
//常被称为“装箱”。

1)显示绑定的变种(硬绑定)

function foo() {
console.log( this.a );
}
var obj = {
a:2
};
var bar = function() {
foo.call( obj );
};
bar(); // 2
setTimeout( bar, 100 ); // 2
// 硬绑定的bar不可能再修改它的this
bar.call( window ); // 2

//在函数bar()内手动调用foo.call(obj),强制将this绑定在obj上
此后不论怎么调用函数bar()都是不会改变this的指向
。**这种绑定是一种显式的强制绑定,因此我们称之为硬绑定**

未完待续…

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值