在理解javascript的this之前,首先先了解一下作用域。
作用域分为两种:
词法作用域和动态作用域的区别是:词法作用域是在写代码或定义时确定的;动态作用域是在运行时确定的。
this的绑定规则
this是在调用时被绑定,取决于函数的调用位置。由此可以知道,一般情况下(非严格模式下),this都会根据函数调用(调用栈)的上下文来绑定对象。
一、默认绑定
默认绑定:默认绑定是指在非严格模式下,且没有使用别的绑定规则时,this根据函数调用(调用栈)的上下文来绑定对象(全局对象)。(严格模式下则绑定undefined)
举个栗子:
function foo() { console.log(this.a);};function bar() { var a = 3; foo();}var a = 2;bar(); //调用栈在全局作用域,this绑定全局对象
运行结果为: 2
//加上"use strict"运行结果则会变成this is undefined
这里的函数调用时,使用了默认绑定,函数调用(调用栈)的上下文是全局作用域,因此this绑定了全局对象(global)。
eg2:
function foo() { console.log(this.a)};var a = 2;(function() { "use strict" foo();})();
运行结果为: 2
这里需要注意:对于默认绑定,决定this绑定对象的不是调用位置是否处于严格模式,而是函数体是否处于严格模式(函数体处于严格模式则this绑定undefined;否则this绑定全局对象)。另外:严格模式和非严格模式虽然有可能可以绑定,但是最好不混用。
间接引用一般也是会应用默认绑定规则。
function foo() { console.log(this.a);};var a = 2;var o = { a: 3, foo: foo };var p = { a: 4 };o.foo(); //3(p.foo = o.foo)(); //2
赋值表达式 p.foo = o.foo的返回值是直接引用目标函数foo。
二、隐式绑定
隐式绑定:由上下文对象调用,绑定到上下文对象。
举个栗子:
function foo() { console.log(this.a);};var obj = { a: 2, foo: foo};obj.foo(); //2foo(); //undefined
这段代码中,foo()被当做引用属性添加到obj对象中,obj调用这个引用属性函数时,会使用该引用属性上下文,this会被绑定到obj对象。(这个函数严格来说不属于obj对象,只是作为引用属性)。属于隐式绑定。
而下面foo()函数的直接执行,并不是obj对象引用,所以上下文对象是全局对象。故this绑定了undefined。属于默认绑定。
新闻热点
疑难解答
图片精选