(笔记)JS之this指向问题

94 阅读2分钟

this的指向问题在前端面试中会经常被问到,所以记录一下,避免以后忘记

注意

  • this是在函数执行的时候才能确定指向谁,在函数定义阶段还不能确定
  • 以下例子是在非严格模式下执行,严格模式下this默认指向undefined
  • es6中this是继承来的,默认指向在定义他时所在的对象
例子1function demo() {
    var name = 'jeck'
    console.log(this.name)
};

demo();    // 打印值为 undefined

demo函数执行的时候是处于window的作用于下面,而window.name = undefined。所以打印值为undefined

例子2var person  = {
    name: 'jeck',
    say: function() {
      console.log(this.name)
    }
};

person.say();    // 打印值为jeck

当执行person的say方法时,由于是由person对象调用的,所以这个时候的this就指向person对象,打印值就为jeck

例子3var person = {
    name: 'jeck',
    b: {
    	say: function() {
    		console.log(this.name)
    	}
    }
}

person.b.say();   // 打印值为undefined

由例子3可以看出,调用say方法的对象是person.b,但是该对象里面没有name属性,所以打印值为undefined(不同于原型链,不会一级一级的往上找name属性)

例子4var person = {
    name: 'jeck',
    b: {
    	name: 'bran',
    	say: function() {
    		console.log(this.name)
    	}
    }
}

var o = person.b.say;
o();   // 打印值为undefined

例子4里面给person里面的b对象定义了name属性,但是打印的还是undefined? 因为执行o方法的时候还是在window环境下,相当于执行window.o(); 所以打印值为undefined

例子5function Person() {
	this.name = 'jeck';
}
var a = new Person();

console.log(a.name)   // 打印值为jeck

在根据构造函数创建实例的时候,其实是先创建一个临时对象,然后把构造函数里面的属性赋值给这个临时对象,然后通过(call, apply. bind)等方式改变this的指向(new关键字的实现原理)

例子6var person = {
	name: '1',
    say: () => {
    	console.log(this.name)
    }
}

person.say();  // 打印undefined

由于es6的箭头函数指向定义时的对象,这里的箭头函数,也就是say,所在的作用域其实是最外层的js环境,因为没有其他函数包裹;然后最外层的js环境指向的对象是winodw对象

例子7var person = {
	name: '1',
    say: function() {
    	const s = () => {
        	console.log(this.name)
        }
        return s
    }
}

person.say()();   // 打印值为1

由于箭头函数s定义是在person对象的作用域,所以打印值为1