this

四种情况:

①   构造函数

复制代码
function Foo(name) {

this.name=name;     

}

var f=new Foo('sunmenghua') ;
console.log(f.name); //this在构造函数中,此处为f //则f.name='sunmenghua''
复制代码

②   对象

复制代码
var obj={
name:"sunmenghua",
printName: function(){
console.log(this.name)
}
}
obj.printName();
//控制台打印出sunmenghua;
//printName为对象属性,函数作为对象属性来执行,则this为对象本身
复制代码

③   函数

复制代码
 function foo(){
console.log(this)
//this===window
//作为函数来执行,则this 为window
}
foo()
复制代码

 

④   call apply  bind

复制代码
function fn(name,age){
console.log(this); //{x:100}
this.name=name;
this.age=age;
console.log(this.name); //sunmenghua
} 
fn.call({x:100},'sunmenghua',11)
//call的第一个参数为this;
//'sunmenghua'为传入fn的第一个参数name
//11为传入fn的第二个参数11
//apply和call相同,apply的第一个参数为this; //只是apply传入函数的参数不是一个个传,要传入一个数组
复制代码

bind()

复制代码
var fn2=function (name,age){
    console.log(this);
    this.name=name;
    this.age=age;
}.bind({x:100})('sunmenghua',11)
 //bind之后带的参数为this; //'sunmenghua'为传入fn2的第一个参数name //11为传入fn2的第二个参数age
//bind之后必须在执行一次;因为call/apply是直接调用目标函数,bind只是返回目标函数,并不调用,所以要执行函数
复制代码

 举例:  

复制代码
var obj ={a:1,
               b:function () {
                      alert(this.a)}
              }; 
var fun =obj.b; 
fun();
复制代码

答案 是什么呢?

不是1;

此处如果是

1 var obj ={a:1,
2                b:function () {
3                       alert(this.a)}
4               }; 
5 obj.b(); 

结果是1;

因为此处是对象调用,如执行obj.b(),this指向obj;

而

复制代码
var obj ={a:1,
               b:function () {
                      alert(this.a)}
              }; 
var fun =obj.b; 
fun();
复制代码

而此处是将obj.b赋值给fun,即将函数赋值给fun,与对象没有关系,则函数的this指向window,window没有定义a属性,则结果为undefined;

总结:

记住 this的值要等到代码真正执行时才能确定
同时this的值具体有以下几种情况:

    1. new 调用时指的是被构造的对象

    2. call、apply调用,指向我们指定的对象

    3. 对象调用,如执行obj.b(),this指向obj

    4. 默认的,指向全局变量window(相当于执行window.fun())

    5. 如果使用了上述多条规则的话,那么排序靠前的将优先控制this的指向。
    6. 在ES2015中的箭头函数,将会忽略上述的所有规则,而将取决与函数创建时的作用域。(箭头函数的作用域在创建时就已经确定,不能更改。想想真是问题终结者...)
posted @ 2020-02-14 10:28  apple78  阅读(139)  评论(0)    收藏  举报