昨天面试被问到this的指向,竟然说的吭哧瘪肚的,也确实毕业半年对于基础的东西在意的越来越少,每天都在无止境的写页面,以后学点记录一点吧~今天先从this开始。
- this指向的是调用其所在函数的对象(非箭头函数)。{1.全局:window;2.函数调用。}
- 构造函数下,this与被创建的新对象绑定。
- 箭头函数下,可以理解为箭头函数根本就没有this,他的this指向取决于定义他时的this指向。(在哪个环境里就指向哪)
1.具体实例分析
function a(){
var x = '小白';
console.log(this.x);//输出undefined
console.log(this);//输出window
}
a();
复制代码
属于第一种情况,this指向的是调用其所在函数的对象,本例中调用所在函数a的为window。
var a ={
var x = '小白';
fn: function(){
console.log(this.x)//输出小白
}
}
a.fn()
复制代码
this指向的是调用其所在函数的对象,此处调用this所在函数的对象为a。
var a = {
var x = '小白';
fn:function(){
console.log(this.x)//输出小白
}
}
window.a.fn()
复制代码
var a= {
x='小黑';
b:{
x='小白';
fn:function(){
console.log(this.x)//输出小白
}
}
}
a.b.fn()
复制代码
通过本例可以得出结论:
1.在非严格模式下,如果一个函数中有this,但是并没有被上级对象所调用,那么this指向window(严格模式下this为undefined);
2.如果一个函数中有this且该函数被上级对象所调用,那么this指向上级对象。
3.如果一个函数中有this,并且该函数中还有多个对象,即使this被最外层的对象所调用,this也只是指向他上一级对象。
var a = {
x='小黑';
b:{
//x='小白'
fn:funciton(){
console.log(this.x)//输出undefined
}
}
}
a.b.fn()
复制代码
函数中有this,最外层的对象a也调用了,但是由于this的上一级对象b中没有x的定义,所以undefined.
var a ={
x= '小黑';
b:{
x='小白';
fn:function(){
console.log(this.x)//undefined
console.log(this)//window
}
}
}
var i =a.b.fn
i()
复制代码
fn虽然是先被b所引用,但是!!!并没有直接执行,所以最后执行的时候指向window。
2.构造函数
function Fn(){
var x = '小白';
}
var a = new Fn()
console.log(a.x) //小白
复制代码
对于构造函数来说,new可以改变this的指向,将其指向对象a。new关键字实际上就是创建一个对象实例,此时只是创建,并没有执行,而调用这个函数Fn的是对象a,所以this就指向了a。(a中有Fn中的user,是因为用new关键字就相当于复制了一份到a中。)
当this遇到了return
function Fn(){
this.x ='小白';
return{};
}
var a =new Fn();
console.log(a.x) //undefined
复制代码
function Fn(){
this.x= '小白';
return function(){}
}
var a = new Fn();
console.log(a.x) //undefined
复制代码
function Fn(){
this.x ='小白';
return undefined
}
var a = new Fn();
console.log(a.x) //小白
复制代码
总结:如果返回值是一个对象,那么this只想这个对象;如果不是对象,那么this还是指向函数实例。另外,null比较特殊,虽然null也是对象,但是如果return null的话,this还是指向函数实例。
apply与call
内部的this绑定在call&apply所指定的第一个对象上,如果不是对象则尝试转化为对象。
function Fn(a,b){
return this.a+this.b+c+d;
}
var c={a:1,b:3};
Fn.call(c,3,4) //1+3+3+4 =11
Fn.apply(c,[3,4]) //1+3+3+4 =11
复制代码
bind
bind是es5引入的,在函数的原型上,Function.prototype.bind
。通过bind绑定之后,函数将会永远被绑定在其第一个参数对象上,不管在什么时候被调用。
箭头函数
- call/apply/bind方法对于箭头函数来说并不改变其this的指向。
- 箭头函数并不绑定自己的this,他会捕获上下文的this,作为自己的this值。
function Fun(){
setTimeout(()=>{
console.log('id:',this.id),1000}) //id为2
}
var id =1;//箭头函数运行时的环境
Fun.call({id:2});//箭头函数定义时的环境
复制代码