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

相关推荐
To_OC2 小时前
LC 207 课程表:刚学图论那会儿,我连这是拓扑排序都没看出来
javascript·算法·leetcode
To_OC3 小时前
LC 208 实现 Trie 前缀树:曾被名字劝退,写完发现是送分题
javascript·算法·leetcode
天渺工作室3 小时前
实现一个adblock/adblock plus等浏览器广告拦截器检测插件
前端·javascript
阳光是sunny4 小时前
Vue 项目怎么做用户行为全链路监控?轻量插件方案详解
前端·面试·架构
ZhengEnCi4 小时前
Q04-Vite禁用CSS代码分割-解决生产环境样式加载顺序混乱问题
前端·vue.js·vite
九酒4 小时前
AI Agent 开发踩坑记:口播功能非得用 APP 原生实现吗?
前端·人工智能·agent
Jackson__5 小时前
做了一段时间的AI coding后,我终于搞清了 CLI 和 MCP 的区别
前端·agent·ai编程
IT_陈寒7 小时前
JavaScript项目实战经验分享
前端·人工智能·后端
用户47949283569158 小时前
6w star,GitHub 趋势第一的 Ponytail,这个agent插件到底在火什么
前端·后端
薛定喵的谔9 小时前
我开源了一个精致的 Next.js 博客模板:Skyplume
前端·前端框架·next.js