默认绑定
先看一段代码
function foo1() { console.log(this) } function foo2() { console.log(this) foo1() } function foo3() { console.log(this) foo2() } foo3()
这段代码的运行结果其实是window,没错,全部都是window.
再来看一段代码
var obj = { name:"lkx", foo: function (){ console.log(this) } } var bar = obj.foo bar()
结果还是window.
这就是this绑定规则之一:默认绑定,判断方法也很简单,我们只需要看函数执行时有没有调用主题,很明显第一段代码和第二段代码全部都没有调用主题,当然也可以说他们都是被window调用的,所以JS引擎会默认将this绑定到全局window上
隐式绑定
再来看一段代码
function foo() { function bar() { console.log(this) } return bar } var fn = foo() fn() //window var obj = { name:"lkx", eating: fn } obj.eating()//调用主题是obj // {name:"lkx",eating: fn}
fn()的结果是window,而obj.eating()的结果是{name:"lkx",eating: fn},就是因为eating()的调用主题是obj,这叫做隐式绑定
隐式绑定的前提条件:
必须在调用的对象内部有一个对函数的引用(比如一个属性)
如果没有这样的引用,在调用时,会报找不到该函数的错误
正是通过这个引用,间接的将this绑定到了这个对象上
显示绑定
当我们不希望在对象内部包含这个函数的引用,同时有希望在这个对象上进行强制调用,就用到了显示绑定
函数的apply和call方法
function foo() { console.log("函数被调用了"+this) } var obj = { name:"obj" } //直接调用和使用方法调用的不同在于this的绑定不同 //直接调用指向的是全局对象(window) foo()//window //可以指定this的绑定对象 foo.call(obj) foo.apply(obj) //call和apply区别 function sum(num1,num2) { console.log(num1+num2,this) } sum.call("call",20,30) sum.apply("apply",[20,30])
函数的bind方法
function foo() { console.log(this) } //默认绑定和显示绑定bind冲突:显示绑定优先级更高 var newFoo = foo.bind("aaa") newFoo() //"aaa"
new绑定
通过new关键字调用一个函数(构造器)时,这个时候this是在调用这个构造器时创建出来的对象
function Person(name,age) { this.name = name this.age = age } var p1 = new Person("lkx",18)
-----------------------------------------------------------------------------------------------
优先级的问题下篇再解释