JS中 this指向的问题

JS中 this指向的问题

知识点补充:
1.在严格版中的默认的this不再是window,而是undefined。
2.new操作符会改变函数this的指向问题。

function Fn(){
    this.num = 1;
}
var a = new Fn();
console.log(a.num); //1

为什么this会指向a?首先new关键字会创建一个空的对象实例a,然后会自动调用一个函数apply方法,将this指向这个空对象,这样的话函数内部的this就会被这个空的对象替代。

重点难点

this的指向在函数定义的时候是确定不了的,只有函数执行 的时候才能确定this到底指向谁,实际上 this的最终指向的是那个调用它的对象

var o = {
    a:10,
    b:{
        a:12,
        fn:function(){
            console.log(this.a); //undefined
            console.log(this); //window
        }
    }
}
var j = o.b.fn;
j();

如果一个函数中有this,这个函数中包含多个对象,尽管这个函数是被最外层的对象所调用,this指向的也只是它上一级的对象

var o = {
    a:10,
    b:{
        a:12,
        fn:function(){
            console.log(this.a); //12
        }
    }
}
o.b.fn();
var o = {
    a:10,
    b:{
        // a:12,
        fn:function(){
            console.log(this.a); //undefined
        }
    }
}
o.b.fn();

一、全局作用域中

this在全局作用域中指window。

//全局作用域中
console.log(this)//window
a =1;
console.log(this.a) //相当于window.a 1
//普通函数中
function fn(){
    console.log(this)
}
fn()//window

二:闭包中指window

示例1

  function fn(){
        function fn2(){
            console.log(this)
        }
        return fn2
    }
    fn()()   //window

示例2

	var myObject = {
		foo:"bar",
		func: function() {
			var self = this;
			console.log("1",this.foo); // bar
			console.log("2",self.foo);// bar
			
			 (function (){
			    console.log("3",this.foo); //此处this指向window  undefined
			    console.log("4",self.foo); // bar
			 }());
		}
	}
	myObject.func();

三:函数调用模式:谁调用就指谁

这里obj.fn()是obj去调用fn,而obj.name=”b”,所以this.name=”b”;
而var fn=obj.fn的时候,fn是window.fn,因此fn()的结果是”a”.
注意:this指向的是上一级调用它的对象,比如obj.fn()与window.obj.fn()都是输出b.

 	var name="a"
    var obj ={
        name:'b',
        fn:function () {
            console.log(this.name)
        }
    }
    obj.fn() //b
    var fn=obj.fn
    fn()     //a

四:构造函数中,this指实例对象。

 	function Person(name,age) {
        this.name=name;
        this.age=age;
    }
    Person.prototype.sayHi=function () {
        console.log('I am '+this.name+',I am '+this.age+' years old.')
    }
    var p1=new Person('张三',20)
    p1.sayHi() //I am 张三,I am 20 years old.

补充:当this碰到return时

示例1

		function fn()  {  
		    this.user = '追梦子';  
		    return {};  
		}
		var a = new fn;  
		console.log(a.user); //undefined

示例2

	function fn()  {  
	    this.user = '追梦子';  
	    return function(){};
	}
	var a = new fn;  
	console.log(a.user); //undefined

示例3

	function fn()  {  
	    this.user = '追梦子';  
	    return 1;
	}
	var a = new fn;  
	console.log(a.user); //追梦子

示例4

	function fn()  {  
	    this.user = '追梦子';  
	    return undefined;
	}
	var a = new fn;  
	console.log(a.user); //追梦子

如果返回值是一个对象,那么this指向的就是那个返回的对象,如果返回值不是一个对象那么this还是指向函数的实例。


示例5

	function fn() {  
	    this.user = '追梦子';  
	    return undefined;
	}
	var a = new fn;  
	console.log(a); //fn {user: "追梦子"}

还有一点就是虽然null也是对象,但是在这里this还是指向那个函数的实例,因为null比较特殊。


示例6

	function fn()  {  
	    this.user = '追梦子';  
	    return null;
	}
	var a = new fn;  
	console.log(a.user); //追梦子

五:apply/call改变this的指向

在 javascript 中,call 和 apply 都是为了改变某个函数运行时的上下文(context)而存在的,换句话说,就是为了改变函数体内部 this 的指向。

主要区别为:apply的第二个参数是散列分布,call则可以是一个数组

六:定时函数中:this指向window

var name = 'window';
var obj = {
    name: 'obj',
    fn: function () {
        var timer = null;
        clearInterval(timer);
        timer = setInterval(function () {
            console.log(this.name);   //window
        }, 1000)
    }
}

七:bind改变this指向

var name = 'window';
var obj = {
    name: 'obj',
    fn: function () {
        var timer = null;
        clearInterval(timer);
        timer = setInterval(function () {
            console.log(this.name);   //obj
        }.bind(this), 1000)
    }
}

bind()的作用类似call和apply,都是修改this指向。但是call和apply是修改this指向后函数会立即执行,
而bind则是返回一个新的函数,它会创建一个与原来函数主体相同的新函数,新函数中的this指向传入的对象。
也因此call/apply不适用于定时函数改变this指向

八:ES6箭头函数:函数体内的this对象,就是定义时所在的对象,而不是使用时所在的对象。

  function foo() {
   setTimeout(() => {
     console.log('id:', this.id);
   }, 100);
 }

 var id = 21;

 foo.call({ id: 42 });
 // id: 42

参考连接 http://www.fly63.com/article/detial/904
https://www.cnblogs.com/pssp/p/5216085.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值