js中this常见的用法
this是函数运行时所在的环境对象,ES6中箭头函数的出现,使得部分开发者有些困惑,我们可以简单概括为:- 在非箭头函数中,this的指向在函数定义时候是确定不了的,this指向调用它的对象。
- 在箭头函数中,this的指向在函数定义时候就已经确定,他会向父级查找。
一般函数的使用
var name='Marai';
function test(){
console.log(this); // Window {postMessage: ƒ, blur: ƒ, focus: ƒ, close: ƒ, parent: Window, …}
console.log(this.name); // Marai
}
test();
window.test();
use strict';
var name='Marai';
function test(){
console.log(this); // undefined
console.log(this.name); // this.html:15 Uncaught TypeError: Cannot read property 'name' of undefined
}
test();
- 默认情况下,执行上下文是全局的,浏览器环境下,this执行window,node环境则为global.
- 一个普通的函数调用,一般this指向为window。
- 上面的test函数执行时,可以理解为是被全局对象window进行调用的,通过打印结果我们可以看出。
- 需要注意的是,如果是在严格模式下,此例的指向为undefined。
对象属性的使用
var name='Marai';
var obj={
name:'name1',
b:{
a:'123',
name:'name2',
fn:function(){
console.log(this);
console.log(this.name);
}
}
}
obj.b.fn(); // {a: "123", name: "name2", fn: ƒ} // name2
var res=obj.b.fn; // Window {postMessage: ƒ, blur: ƒ, focus: ƒ, close: ƒ, parent: Window, …}; // Marai
res();
- 上面obj.b.fn是通过obj.b来进行调用的,所以this指向obj.b,打印出b的name,也就是name2。
- res()为什么会打印出全局对象Maria呢???
- 因为obj.b.fn赋值给了res,此时调用res的对象是省略的全局对象window,所以this指向window。
事件绑定中的this指向
- 直接在DOM元素上绑定事件,打印出的this是全局变量window。
- IE attachEvent绑定事件,this指向全局变量 window。
- 通过onclick绑定事件,此时的this指向该元素。
- 通过 addEventLister绑定事件,此时this指向该元素。
<div onclick="handleClick()">hello world</div>
<div id="test">hello world2</div>
function handleClick(){
console.log(this);
}
// Window {postMessage: ƒ, blur: ƒ, focus: ƒ, close: ƒ, parent: Window, …}
document.getElementById('test').addEventListener('click',function(){
console.log(this);
});
// <div id="test">hello world2</div>
构造函数中的使用
构造函数中this的指向为当前实例,具体可以了解new关键字相关知识。
function Person(){
this.name='Kangkang';
console.log(this)
}
var p=new Person();
console.log(p.name); // Kangkang
箭头函数中this的指向
document.getElementById('test').addEventListener('click',function(){
console.log(this); // <div id="test">hello world2</div>
});
document.getElementById('test').addEventListener('click',()=>{
console.og(this); // window
});
var name='Maria';
var obj2={
name:'name1',
b:{
a:'123',
name:'name2',
fn:function(){
console.log(this.name);
},
fn2:()=>{
console.log(this.name)
}
}
}
obj2.b.fn(); // name2
obj2.b.fn2(); // Maria
- 箭头函数本身不会含有this指向,this会向上进行查找。
- 示例1,绑定事件,默认this指向该元素,我们使用箭头函数,this就会向上查找,找到window。
- 示例2,fn2,本身没有this,箭头函数会继承外层函数调用的this绑定,此例指向window。
测试一下
var age=100;
var obj={
age:50,
say:function(){
console.log(this.age);
}
}
obj.say();
var age=100;
var obj={
age:50,
say:()=>{
console.log(this.age);
}
}
obj.say();
var a=100
function test1(){
this.a=22;
let b=function(){
console.log(this.a);
};
b();
}
var age=new test1();
var a=100;
function test2(){
this.a=50;
let b=()=>{console.log(this.a)}
b();
}
var age=new test2();
50,100,100 50