this的深入解析,从最简单出发

对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绑定问题而导致的错误。

相关推荐
NiNg_1_23416 分钟前
npm、yarn、pnpm之间的区别
前端·npm·node.js
秋殇与星河18 分钟前
CSS总结
前端·css
NiNg_1_23419 分钟前
Vue3 Pinia持久化存储
开发语言·javascript·ecmascript
读心悦20 分钟前
如何在 Axios 中封装事件中心EventEmitter
javascript·http
BigYe程普40 分钟前
我开发了一个出海全栈SaaS工具,还写了一套全栈开发教程
开发语言·前端·chrome·chatgpt·reactjs·个人开发
神之王楠1 小时前
如何通过js加载css和html
javascript·css·html
余生H1 小时前
前端的全栈混合之路Meteor篇:关于前后端分离及与各框架的对比
前端·javascript·node.js·全栈
程序员-珍1 小时前
使用openapi生成前端请求文件报错 ‘Token “Integer“ does not exist.‘
java·前端·spring boot·后端·restful·个人开发
axihaihai1 小时前
网站开发的发展(后端路由/前后端分离/前端路由)
前端
流烟默1 小时前
Vue中watch监听属性的一些应用总结
前端·javascript·vue.js·watch