对JavaScript中的this进行全面深入的讨论是一个广阔而复杂的话题。了解和正确使用this对于JavaScript程序员来说至关重要,因为它影响到代码的行为和结果。在本文中,我们将探讨this的概念,以及它如何在不同的情况下工作。我们还将深入研究箭头函数对this的影响,并提供一些实际的例子来帮助读者更好地理解这个概念。
什么是this?
在JavaScript中,this是一个关键字,它指向当前执行代码的对象,可以简化代码的书写。然而,this的值并不是在编写代码时确定的,而是在运行时动态确定的,这使得它成为一个相对复杂的概念。先来看一段this的简单例子:
js
let obj = {
name:'陈总',
say:function(){
console.log(obj.name); // (this.name)效果一样
}
}
obj.say() //打印名字
不过要理解this的行为,我们需要考虑几种不同的绑定规则,包括默认绑定、隐式绑定、显式绑定和new绑定。
默认绑定规则
默认绑定规则:函数在哪个词法作用域中生效,this就指向哪里(独立调用的函数this都指向window)
实例一
js
var a = 1
function foo(){
console.log(this.a); //this代表foo,指向全局,
}
foo()
用node这段代码会打印undefined,但是在浏览器上就会是这样
因为this代表foo,指向全局
实例二
js
var a = 1
function foo(){
console.log(this.a);
}
function bar(){ //bar 的词法作用域是window
var a = 2
foo() //foo()在bar的作用域生效,但是此时必须要知道bar的词法作用域是谁
}
bar()
foo()在bar的作用域生效,但是此时必须要知道bar的词法作用域是谁,bar 的词法作用域是window,foo是被独立调用的(只有foo())。
隐式绑定规则
隐式绑定规则:当一个函数被对象所拥有且调用时,函数的this指向该对象
实例
js
function foo(){
console.log(this.a);
}
var obj = {
a :1,
foo:foo
}
obj.foo()
obj对象引用foo函数,所以this指向obj,可以打印a。
隐式丢失
隐式丢失:当函数被多个对象链式调用时,this指向引用函数的那个对象
实例
js
function foo(){
console.log(this.a);
}
var obj = {
a :1,
foo:foo //引用foo函数,所以this指向obj
}
var obj2 = {
a:2,
obj:obj
}
obj2.obj.foo()
显式绑定
显式绑定:通过call、apply和bind方法,我们可以显式地指定函数中的this指向。
call()
js
function foo(){
console.log(this.a);
}
var obj = {
a:1
}
foo.call(obj)
直接调用 foo() 无法让this指向obj,this会指向window。(如果foo有参数,call可以传参:foo.call(obj,4,5)
)
apply()
js
function foo(x,y){
console.log(this.a,x+y);
}
var obj = {
a:1
}
foo.apply(obj,[4,5]) // 它接受参数是以数组形式传参
apply()和call()的区别在于传参的方式。
bind()
js
function foo(x,y){
console.log(this.a,x+y);
}
var obj = {
a:1
}
let bar =foo.bind(obj,4)
bar(5)
可以在bind里面传一个(另一个放在bar)或两个,优先使用bind里面的参数
new绑定
new 绑定:当使用new关键字来调用构造函数时,构造函数内部的this会指向新创建的实例对象。
js
function Car(ower,color){
this.name = 'BMW'
this.long = 4900
this.height = 1400
this.ower = ower
this.color = color
}
let car = new Car('李总','red')
this都是指向car
箭头函数对this的影响
箭头函数没有this这个概念,写在箭头函数的this也是它外层普通函数的this 。
js
var obj ={
a:1
}
var foo = () =>{ //箭头函数
console.log(this.a);
}
foo.call(obj)
使用call()方法都无法让this指向obj,因为箭头函数没有this。
js
// 下面的this都是foo的
var obj ={
a:1
}
function foo(){
var bar = ()=>{
console.log(this);
var baz = ()=>{
console.log(this);
}
baz()
}
bar()
}
foo.call(obj)
this不在foo但是foo可以用call()调用并打印两个a:1,所有this都是foo的
总结
在本文中,我们深入探讨了JavaScript中this的概念及其各种绑定规则,以及箭头函数对this的影响。正确理解和使用this对于编写高质量的JavaScript代码至关重要,希望本文能够帮助读者更好地掌握这一关键概念。在实际编程中,建议通过大量的练习和实践来加深对this的理解,并时刻注意避免由于this绑定问题而导致的错误。