this

调用位置:函数在代码中调用的位置,而不是声明的位置。

调用栈:为了到达当前执行位置的所有调用的函数。

例子:

   

function baz(){

     //当前调用栈为baz

    //调用位置是全局作用域

    console.log("baz");

    bar(); //bar的调用位置

}

   function bar(){

    //当前调用栈为bar->baz

    //调用位置是baz

    console.log("bar");

    foo(); //foo调用位置

}

   function foo(){

   //当前调用栈为foo->bar->baz

  //调用位置是bar

   console.log("foo");

}

调用位置则是调用栈的第二个元素,可以使用调试器找出调用栈。

函数执行过程中如何使用调用位置决定this的绑定对象。

this绑定有四种规则:

1.默认绑定:this指向全局对象,可以看做无法应用其他规则时的默认规则。

  

function foo(){

    console.log(this.a);

}

  var a = 2;

  foo() // 2

通过分析调用位置,发现foo()是直接使用不带任何修饰的函数进行调用的。

2.隐式绑定:调用位置是否有上下文。

function foo(){

   console.log(this.a);

}

  var obj = {

     a:2,

     foo:foo

};

  obj.foo() //2

 

调用位置会使用obj上下文来引用函数。注意,当使用回调函数时,因为函数作为参数传入时,实际上是一个隐式赋值操作,如下:

 function foo(){

   console.log(this.a)

}

 function doFoo(fn){

   //fn其实引用的是foo

   fn(); //调用位置

}

 var obj ={

   a:2,

   foo:foo

}

var a = "global";

 doFoo(obj.foo); //"global"

 

3.显式绑定:即使用call,apply,bind等内置函数修改this的值。

var obj ={
  a:2
}
function d (){
   console.log(this.a)
}
d.call(obj); //2


显式绑定中有一种硬绑定:用于为了保证this不缺失,如下:

  

var obj ={
  a:2
}
var abc = function(){
  d.call(obj);  

//d函数的this一直指向了obj

}
function d (){
   console.log(this.a)
}
abc(); //2  

4:new绑定。(Js中的new与其他语言完全不同)

  new操作有以下四个步骤:

  1.创建一个全新的对象。

  2.这个对象会被执行原型链接。

  3.这个对象会绑定到函数调用的this.

  4.如果函数没有返回其他对象,则new表达式中的函数调用自动返回这个对象。

 

 function foo(){

    this.a =2;

}

  var baz = new foo();

  console.log(baz.a);  //2

最后是优先级:

   new>显示>隐式>默认。

   具体例子可参考书P91~P。。。

  

原文地址:https://www.cnblogs.com/Darlietoothpaste/p/6391307.html