this指向问题

121 阅读2分钟
this指向问题

this:函数执行的主体(谁执行的函数)

  • 事件绑定
  • 函数执行 [普通函数执行,成员访问,匿名函数,回调函数...]
  • 构造函数
  • 箭头函数 [生成器函数generator]
  • 基于call/apply/bind强制修改this指向
事件绑定
  • DOM0:xxx.onclick = function(){}

  • DOM2:

    • xxx.addEventListener('xxx',function(){})
    • xxx.addachEvent('onclick',function(){}) // IE6~8

    给元素的某个事件行为绑定方法「DOM0 & DOM2」,当事件行为触发,方法执行,方法中的THIS是当前元素本身

判断this技巧

函数执行,看方面前面是否有“点”

@1 有“点”:“点”前面是谁,THIS就是谁

@2 没有“点”:方法中的THIS是window(非严格模式)/undefined(严格模式)

@3 立即执行函数this指向window/undefined

例题
var num = 10;				//=>65
var obj = {
    num: 20					//=>30
};
obj.fn = (function (num) {
    this.num = num * 3;
    num++;					//=>21
    return function (n) {
        this.num += n;		
        num++;
        console.log(num);	//=>22	23
    }
})(obj.num);
var fn = obj.fn;
fn(5);
obj.fn(10);
console.log(num, obj.num);	//65 30
let obj = {
    fn: (function () {
        return function () {
            console.log(this);
        }
    })()
};
obj.fn();			//=>obj
let fn = obj.fn;	
fn();				//=>window
/*
	obj.prop调用指向obj.prop
*/
var fullName = 'language';
var obj = {
    fullName: 'javascript',
    prop: {
        getFullName: function () {
            return this.fullName;
        }
    }
};
console.log(obj.prop.getFullName());	//=>undefined
var test = obj.prop.getFullName;
console.log(test());	//=>language
var name = 'window';
var Tom = {
    name: "Tom",
    show: function () {
        console.log(this.name);
    },
    wait: function () {
        var fun = this.show;
        fun();
    }
};
Tom.wait();		//=>window
window.val = 1;
var json = {
    val: 10,
    dbl: function () {
        this.val *= 2;
    }
}
json.dbl();			//=>20
var dbl = json.dbl;
dbl();				//=>2
json.dbl.call(window);	//=>4
alert(window.val + json.val);	//=>24
(function () {
    var val = 1;
    var json = {
        val: 10,
        dbl: function () {
            val *= 2;	//=>2
        }
    };
    json.dbl();
    alert(json.val + val);	//=>12
})();
var x = 3,//=>12 13 234
    obj = {
        x:5		//=>95
    };	
obj.fn = (function (){
    this.x *= ++x;	
    return function (y){
        this.x *=(++x) + y;
        console.log(x)	//13 234
    }
})();
var fn = obj.fn;
obj.fn(6);
fn(4);
console.log(obj.x,x);	//95 234
/*
	注意:函数才是谁调用this指向谁
*/
var obj = {   
     a: 10,
     b: this.a + 10, //这里的this指向window(全局),a为undefined  ==>  undefined + 20 = NaN
     fn: function () {
         return this.a;
       }
 }
console.log(obj.b);        //NaN
console.log(
    obj.fn(),         //10
    obj.fn            //fn
);  
var a = 5;
 function fn1(){
     var a = 6;
     console.log(a);        //6
     console.log(this.a);   //5
 }  
 function fn2(fn) {
     var a = 7;
     fn();
} 
 var obj = {
     a: 8,
     getA: fn1
 }  
fn2(obj.getA); 
var obj = {
foo: "test",
fn: function(){
        var mine = this;
        console.log(this.foo);       //test
        console.log(mine.foo);       //test

        (function(){
          console.log(this.foo);    //undefined
          console.log(mine.foo);    //test
        })();  
    } 
};
obj.fn();
function foo(){
    console.log(this.a);
}
var a = 2;
var o = {
    a:3, 
    foo: foo
};
var p = { a:4 };
o.foo();  //3
//
(p.foo = o.foo)();      //=>2
p.foo = o.foo;
p.foo(); //=>4
function test(arg) {
    this.x = arg;
    return this;
} 
var x = test(5); 
var y = test(6);    
console.log(x.x);	//=>相当于window下的window undefined
console.log(y.x);   //=>6
var obj = {
    data: [1,2,3,4,5],
    data2: [1,2,3,4,5],
    fn: function () {
       console.log("--test--");
       console.log(this);   
       return this.data.map(function (item) {
             console.log(this);   
             return item * 2;
        }); 
    },
    fn2: function () {
       console.log("---test2---");
       console.log(this);   
       return this.data2.map(item=>{
           console.log(this);  
           return item * 2; 
       });
    }
 };  
 obj.fn();
 obj.fn2();