this指向

this是运行时进行绑定的,并不是在编写时绑定,它的上下文取决于函数调用时的各种条件。this的绑定和函数声明的位置没有任何关系,只取决于函数的调用方式。它既不指向函数自身也不指向函数的词法作用域。
函数调用时,会创建一个活动记录(有时也称为执行上下文) ,这个上下文中会记录包含函数在哪里被调用(调用栈)、函数的调用方法、传入的参数等信息。this是其中的一个属性。
1. 默认绑定
this指向全局对象。
示例:

function foo(){
 console.log(this.a);
}
var a=2;
foo();//2

    这里的this.a的this指向了window。
 2. 隐式绑定
调用位置是否有上下文对象,或者说是否被某个对象拥有或者包含。
示例:

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

foo函数严格来说并不属于obj对象,但调用位置会使用obj上下文来引用函数,因此可以说函数被调用时obj对象“拥有”或者“包含”它。
隐式丢失
被隐式绑定的函数会应用默认绑定,把this绑定到全局对象或者undefined上(跟严格模式有关)。
示例:

function foo(){
  console.log(this.a);
}
var obj={
  a:2,
  foo:foo
}
var a="gloal";
var bar=obj.foo;
bar();//gloal

这个时候的bar其实是函数foo的引用,此时的bar是不带任何修饰的函数调用。
传入回调函数时,也会发生此种情况。示例:

function doFoo(fn){
  fn();
}
function foo(){
  console.log(this.a);
}
var obj={
  a:2,
  foo:foo
}
var a="gloal";
doFoo(obj.foo);//gloal

传入内置的函数结果是一样的。示例:

function foo(){
  console.log(this.a);
}
var obj={
  a:2,
  foo:foo
}
var a="gloal";
setTimeout(obj.foo,100);//gloal

setTimeout的源代码与下面代码类似:

function setTimeout(fn,delay){
  fn();
}

上面的例子可以稍稍修改下,this的指向就改变了,可以先想想要怎么去改?

改完之后

function foo(){
  console.log(this.a);
}
var obj={
  a:2,
  foo:foo
}
var a="gloal";
setTimeout(function(){obj.foo();},100);//2

3. 显示绑定
 call([thisObj[,arg1[, arg2[,   [,.argN]]]]])
apply([thisObj[,argArray]])
它们第一个参数是一个对象,会把这个对象绑定到this。这两个函数的区别在于参数,call的其它参数直接传递,apply则以数组的形式传递给函数。
硬绑定
ES5提供了两个内置的方法,Function.prototype,bind。
用法如下:
4. new绑定
使用new来调用函数,会执行下面的操作。
1. 创建(构造)一全新的对象。
2. 这个对象会被执行原型连接。
3.这个对象会绑定到函数调用的this。
4.如果函数没有返回其它对象,new的函数调用机会自动返回这个新对象。

function foo(a){
  this.a=a;
}
var bar=new foo(2);
console.log(bar.a);//2

用new来调用foo(...)时,会构造一个新对象并把它绑定到foo(...)调用中的this上。

被忽略的this
null或者undefined作为this的绑定对象传入call 、apply、或者bind时,应用的是默认绑定规则。

检测题:

function Foo(){
this.a=1;
this.param={
      "name":this.a
    };
}

var bar= new Foo();
    bar.name=2;
alert(bar.param.name);

答案是:1 。

注意此处是构造函数。

原文地址:https://www.cnblogs.com/cheemon/p/6038239.html