每个函数的this是在调用时被绑定的,完全取决于函数的调用位置;
什么是调用位置呢?
顾名思义就是“函数被调用的位置”;要去寻找被调用的位置,那么就要分析调用栈,this的调用位置就在当前正在执行的函数的前一个调用中;
举个例子
function baz() { // 当前调用栈是全局 -> baz,调用位置是上一个执行栈就是全局作用域 bar() // bar的调用位置 } function bar() { // 当前调用栈是全局 -> baz -> bar,调用位置是上一个执行栈就是baz foo() // foo的调用位置 } function foo() { // 当前调用栈是全局 -> baz -> bar -> foo,调用位置是上一个执行栈就是bar } baz() // baz的调用位置 接下来我们看看再函数的执行过程中调用位置是如何决定this的绑定对象的。 this绑定有四条规则,分别是: a.默认绑定 b.隐式绑定 c.显式绑定 d.new绑定 四种规则分别从弱到强,new绑定优先级最高,依次类推; 默认绑定 可以把这条规则是无法应用其他规则时的默认规则; function foo() { // this指向全局 console.log(this.a) } a = 1; foo(); // 输出1 这里由于foo函数时直接引用进行调用的,只能使用默认绑定,无法应用其他规则,所以this指向全局对象,而全局变量a为1,所以输出1; 需要注意的是:再严格模式下,this会绑定到undefined,而不是全局对象; 隐式绑定 调用位置是否有上下文对象是隐式绑定需要考虑的规则,或者说是否被某个对象引用; function foo() { console.log(this.a) } var obj = { a: 1, foo: foo } obj.foo(); // 输出1 可以看到,obj对象的foo属性添加了foo函数的引用,当foo被调用时,指向了obj对象,当函数引用有上下文对象时,隐式绑定规则会把this绑定到这个上下文对象,即obj对象; 注意:对象属性引用链中只有最后一层会影响调用位置,举个例子:function foo() { console.log(this.a) } var obj1 = { a: 1, obj2: obj2 } var obj2 = { a: 2, foo: foo } obj1.obj2.foo(); // 输出2 显式绑定 其实这种方法很常见,就是通过call/apply/bind等强绑定,可以直接指定this的绑定对象。这里就不展开描述了 new绑定 相信大家对new构造函数调用都耳熟能详,使用new调用函数,对自动执行下面的操作: a.创建一个全新的对象; b.这个新对象会被执行原型连接; c.这个新对象会被绑定到函数调用的this; d.如果函数没有返回其他对象,那么new表达式中的函数调用会自动返回这个新对象; 看以下代码 function foo() { this.a = a; } var bar = new foo(2); console.log(bar.a); // 2 使用new来调用foo()时,会构造一个新对象并把它绑定到foo()调用中的this上。 接下来总结一下如何判断this 1、函数是否再new中调用?是的话this绑定的是新创建的对象; 2、函数是否通过call/apply调用?是的话this绑定的是指定的对象; 3、函数是否在某个上下文对象中调用?是的话this绑定的是那个上下文对象; 4、如果都不是以上,使用默认绑定,如果在严格模式下,被绑定到undefined,否则就绑定到全局对象; 以上就是this的绑定原理啦~ 标签:调用,bar,对象,绑定,new,规则,设计,foo From: https://www.cnblogs.com/heyujun-/p/17278621.html