JavaScript中this的指向问题分享
写在前面的说明:
这里就是自己学习记录理解的this指向问题,有些也是有借鉴一些大神文章,如果不全或者错误的请大神指教,理解 谢谢!
这里抛出出一个常见的this指向问题
<div id="box">div</div>
<script>
var box=document.getElementById('box');
box.οnclick=function(){
setTimeout(function(){
this.style.backgroundColor='red';
},1000)
}
</script>
//Chrome下抛出:
//Uncaught TypeError: Cannot set property 'backgroundColor' of undefined at ...
解决办法:定时器中的this指向是window 解决办法 var that=this 这里的this的指向是box
<script>
var box=document.getElementById('box');
box.οnclick=function(){
//定时器中的this指向是window 解决办法 var that=this 这里的this的指向是box
var that=this
setTimeout(function(){
this.style.backgroundColor='red';
},1000)
}
</script>
正文开始
1.1.全局作用域或者普通函数中 this 指向全局对象 window(全局环境)
//直接打印
console.log(this) //window
//function声明函数
function fn() {console.log(this)}
fn() //window
//function声明函数_这里有个严格模式:
function fn(){
"use strict"
console.log(this);
}
fn();//undefined
//function声明函数赋给变量
var fn = function () {console.log(this)}
fn() //window
//自执行函数
(function () {console.log(this)})(); //window
1.2.call()和bind改变this指向
//call()
function fn1(){
console.log(this.a);
}
fn1.call({a:1});//1 call方法会立即执行,同时 函数主体里的this会立即指向{a:1}这个对象
function fn2(m,n){
console.log(this.a,m,n);
}
fn2.call({a:1},2,3);//1 2 3
//函数.call会直接调用该函数,并且call的第0个参数就是函数执行的this
// 后面的参数是函数执行的参数
//bind()
function fn(m,n){
console.log(this.a);
}
var fn1=fn.bind({a:2});//bind函数是返回一个新的函数
var fn2=fn.bind({a:3});
var fn3=fn.bind({a:4});
console.log(fn1)
console.log(fn2)
console.log(fn3)
fn1()//2
fn2()//3
fn3()//4
----这里以上的bind绑定后的新函数 fn 指向的this就是 bind(后面的的对象了)
同时注意一点
绑定过后的fn1函数 如果在绑定bind的指向就是第一次绑定的对象()
//==============================================
function fn(){
console.log(this);
}
var fn1=fn.bind(1)
fn1()//number:1
2.方法调用中谁调 this 就指谁(事件处理函数)
<div id="oo" οnclick="console.log(this)"></div>
this的指向:<!--this指的是 <div id="oo" οnclick="console.log(this)"></div>-->
<div id="oo" οnclick="(function(){console.log(this)})()"></div>
this的指向:<!--window-->
<div id="box">1111</div>
//对象方法调用
var box= {
fn: function () {console.log(this)}
}
box.run() // box
//事件绑定
var box=document.getElementById('box');
box.onclick = function () {
console.log(this) // 事件处理函数中this 该事件右谁触发 就是指的是谁 <div id="box">1111</div>
}
//事件监听
var box= document.querySelector("#box")
box.addEventListener('click', function () {
console.log(this) //box //<div id="box">1111</div>
})
3.构造函数
//不使用new指向window
function Fn(name) {
console.log(this) // window
this.name = name;
}
Fn('pets')
//使用new 构造
function Fn(name) {
this.name = name
console.log(this) //fn
self = this
}
var fn= new Fn('pets')
console.log(self === fn) //true
//这里new改变了this指向,将this由window指向Fn的实例对象fn
function Fn(){
this.a=1;
return 1;//如果返回非NaN,那么实例化结果就是返回出对象
}
var f=new Fn();
console.log(f);//{a:1}
//===============================================
function Fn1(){
this.a=1;
return {}; //如果返回非NaN,那么实例化结果就是返回出对象
}
var f1=new Fn1();
console.log(f1);//{}
//=======================================================
4.原型链
var p={
a:1,
fn:function(){
console.log(this.a);
}
}
var c=Object.create(p);//这里是从母本p上创建一个c,也就是c上有个__proto__指向p
// console.log(c)//{}
// console.log(c.__proto__)//{a: 1, fn: ƒ}
// console.log(c.a)//1
c.fn()//1
5.箭头函数
var fn=()=>{
console.log(this);
}
fn()//Window
//在箭头函数定义的时候,fn指谁那么箭头函数中this就是指谁
// 这里是是fn()自己的的调用 所以指向window
box.οnclick=function(){
setTimeout(()=>{
this.style.backgroundColor="red";
},500)
}
//这里的this指向box
//================================================
var fn=()=>{
console.log(this);
}
var fn9=fn.bind({})
fn9()//window 这里是无法通过bind改变其this的指向的
6.1对象内
var a=1;
var obj={
a:2,
fn1:function(){
console.log(this.a);
}
}
obj.fn1()//2
obj.fn1.bind({a:"pets"})()//pets
//=====================================
var obj={
a:1
}
var fn=function(){
console.log(this.a);
}
obj.fn=fn;
obj.fn();//1
//============================================
var obj={
a:1
}
var fn=function(){
console.log(this.a);
}
obj.fn=fn;
var fn1=()=>{
console.log(this.a);
}
obj.fn1=fn1;
obj.fn()//1
obj.fn1();//window
//=========================================
var a=1;
var obj={
a:2,
o:{
a:3,
fn:function(){
console.log(this.a);
}
}
}
obj.o.fn();//3 就近绑定
var temp=obj.o.fn;
temp()//1
6.2.对象内函数定义箭头函数
var a=1;
var obj={
a:2,
fn1:()=>{
console.log(this.a);
},
fn2:function(){
console.log(this.a)
}
}
//箭头函数是谁申明我就更谁跑,
obj.fn1();//1 this的这里指的是window,
//function是谁调用它,他的this指针就是谁,这里是obj进行的调用 所以最后是取了 obj中的a的值
obj.fn2();//2 this的这里指的是obj
6.3.对象内函数返回箭头函数
var a=1;
var obj={
a:2,
fn1:function(){
return function(){
console.log(this.a);
}
},
fn2:()=>{
return ()=>{
console.log(this.a)
}
},
fn3:function(){
return ()=>{
console.log(this.a);
}
}
}
var innerFn1=obj.fn1();
innerFn1()// 1
//箭头函数在哪里出生 this 就指向谁;
var innerFn2=obj.fn2();
innerFn2()//1
var innerFn3=obj.fn3();
innerFn3()//2
后续还有set和get的设置中this的指向…继续学习吧…
–end–