透彻认识function中的this在不同调用环境下的指向
事件调用环境 谁触发事件,函数里的this就指向谁
例:
<div class="box"></div>
var box=document.querySelector('.box');
box.onclick=move;
function move(){
this.style.left=100+'px';
}
全局环境
- 指向window(浏览器运行的环境)
console.log(this);
- 在单独的js文件中,全局的this指向的是导出的对象(node运行的环境下) this.js
console.log(this===module.exports); // true
终端运行命令
node this.js
函数内部
this最终指向的是调用它的对象
- 普通函数直接调用与window调用
move(); // 非严格模式下指向的是window,严格模式下是undefined
// 严格模式下,调用
window.move(); // window
- 对象的函数直接调用与window调用
var obj={
a:10,
b:function(){
console.log(this)
}
}
obj.b(); // 指向obj
window.obj.b(); // 指向obj
函数被多层对象所包裹,如果函数被最外层对象调用,this指向的也只是它上一层的对象
例:
var obj={
a:10,
b:{
fn:function(){
console.log(this);
}
}
}
window.obj.b.fn; // 指向b
var abc=obj.b.fn;
abc(); // 指向的是window,this最终指向的是调用它的对象
- 多层对象中的函数this的指向
- 对象中的函数被赋值给另一个变量
构造函数中的this指向的是实例对象
例
function fn(){
this.num=10;
console.log(this);
}
var obj=new fn();
console.log(obj.num) // 10
fn.num=20;
fn.prototype.num=30;
fn.prototype.method=function(){
console.log(this.num);
}
var prototype=fn.prototype;
var method=prototype.method;
new fn().method(); // 10 ,new fn={}即{}.method();
prototype.method() //30 prototype={}
method() //undefined method指向window
/*
* 1.调用函数
* 2.自动创建一个对象
* 3.把创建出来的对象和this进行绑定
* 4.如果构造函数没有返回值,隐式返回this对象
*/
- 构造函数中的this指向
- new运算符的作用
如果构造函数中有return 如果return的值对象,this指向返回的对象,如果不是对象,则this指向保持原来的规则,在这里null比较特殊
function fn(){
this.num=10;
return ''; // 返回'',1,null 时obj.num为10,返回[],{}时,obj.num为undefined
}
var obj=new fn();
console.log(obj.num);
了解箭头函数中的this指向的特殊性
- 箭头函数本身是没有this和arguments,在箭头函数中引用this实际上调用的是定义时的上一层作用域的this,上一层作用域,因对对象是不能形成对立的作用域的。
function move(){
var _this=this;
setTimeout(function(){
_this.style.left='200px';
})
}
// es6写法
function move(){
setTimeout(()=>{
this.style.left='200px';
})
}
var obj={
fn:()=>{
console.log(this);
}
}
obj.fn(); // this指向window
掌握如何改变this指向
改变this指向的方法: call(this,a,b,c) apply(this,[abc]) bind(this,a,b,c)()
var box=document.querySelector('.box'),a,b,c;
var obj={
fn:()=>{
console.log(this);
},
fn1:function(){
console.log(this)
}
}
obj.fn.call(box); // 指向window
obj.fn1.call(box,a,b,c);
obj.fn1.apply(box,[a,b,c]);
obj.fn.bind(box)();