这是我的第一篇掘金博客,开启掘金写作之路。
在学习JavaScript函数部分时,对于this指向问题有很大的疑惑。为了彻底搞懂 JS 中 this 机制,我通过某站和博客进行学习,我总结了以下三种情况。
实在搞不清楚时候,我都是这样来记的:不管函数是按哪种方法来调用的,谁调用这个函数或方法,this关键字就指向谁。
一、函数调用中this的指向
1.全局环境
全局环境下this就是window对象的引用
<script>
console.log(this == window); //true
console.log(this instanceof Object); //true
</script>
2.类中的方法
this指的是当前对象
let obj ={ name:'simonzhangs',
show:function(){ console.log(this);
return this.name; } }
console.log(obj.show());//{name: 'simonzhangs', show: ƒ}
//simonzhangs
3.类中的方法中函数
在该函数中,是普通函数,this指的是window对象
let obj ={ name:'simonzhangs',
show:function(){
function show2(){
console.log(this);
} show2();
}
}
console.log(obj.show());
二、方法调用中this的指向
可以使用构造函数和对象字面量来创建对象,上面提到函数为对象的方法时this 指向该对象。以下为两种创建对象方法实例:
1.构造函数方法
函数当被 new 时即为构造函数,一般构造函数中包含属性与方法。函数中的上下文指向到实例对象。
构造函数主要用来生成对象,里面的this默认就是指当前对象
function User() {
this.name = "simonzhangs";
this.say = function() {
console.log(this); //User {name: 'simonzhangs', say: ƒ}
return this.name;
};
}
let juejin = new User();
console.log(juejin.say()); //simonzhangs
2.对象字面量方法
下例中的show1函数不属于对象方法所以指向window
show属于对象方法执向 obj对象
let obj = { site: "juejin",
show() { console.log(this.site); //juejin
console.log(`this in show() method: ${this}`); //this in show() method: [object Object]
function show1() {
console.log(typeof this.site); //undefined
console.log(`this in show1() function: ${this}`); //this in show1() function: [object Window] }
show1(); } };
obj.show();
3.在方法中使用函数可以改变this指向
如forEach,当然还包括apply/call/bind
在show方法中,使用map函数,增加this参数可将this指向当前对象
let Lesson = { site: "掘金",
lists: ["后端", "前端", "Android"],
show() { return this.lists.map(function(title) {
return `${this.site}-${title}`;
}, this);
}
};
console.log(Lesson.show()); //['掘金-后端', '掘金-前端', '掘金-Android']
也可以在父作用域中定义引用this的变量,将函数中的this指向当前对象,而不是window对象
let Lesson = { site: "掘金",
lists: ["后端", "前端", "Android"],
show() {
const that = this;
return this.lists.map(function(title) {
return `${that.site}-${title}`;
});
}
};
console.log(Lesson.show());//['掘金-后端', '掘金-前端', '掘金-Android']
三、箭头函数中没有this
箭头函数没有this, 也可以理解为箭头函数中的this 会继承定义函数时的上下文,
可以理解为和外层函数指向同一个this。
1.如果想使用函数定义时的上下文中的this,可以选择使用箭头函数
未使用箭头函数时,返回的是window对象下name属性值
var name = 'juejin';
var obj = {
name: 'juejin-js',
getName: function () {
return function () {
return this.name;
}
}
}
console.log(obj.getName()()); //返回window.name的值juejin
使用箭头函数时,this 为定义该函数的上下文,即为定义时父作用域中的this,指向的是obj
var name = 'juejin';
var obj = {
name: 'juejin-js',
getName: function () {
return () => this.name;
}
}
console.log(obj.getName()()); //返回obj.name的值juejin-js
2.涉及dom对象操作时,this指向的情况
在bind()方法中,使用addEventListener来监听dom元素,此时this指向的是dom对象,即button标签
<body>
<button btn="juejin-js">button</button>
<script>
let Dom = {
site: "juejin",
bind:function() {
const btn= document.querySelector("button");
btn.addEventListener("click", function() {
console.log(this.getAttribute("btn")); //juejin-js
});
}
};
Dom.bind();
</script>
</body>
在使用箭头函数时,this则执行上下文对象,要想获取dom对象,需要用到event对象来获取。
<body>
<button>button</button>
</body>
<script>
let Dom = { site: "juejin",
bind() {
const button = document.querySelector("button");
button.addEventListener("click", event => {
alert(this.site + event.target.innerHTML); //juejinbutton
});
}
};
Dom.bind();
</script>
欢迎大家在评论区提出意见和建议!