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

相关推荐
恋猫de小郭3 分钟前
为什么跨平台框架可以适配鸿蒙,它们的技术原理是什么?
android·前端·flutter
云浪6 分钟前
元素变形记:CSS 缩放函数全指南
前端·css
明似水21 分钟前
用 Melos 解决 Flutter Monorepo 的依赖冲突:一个真实案例
前端·javascript·flutter
独立开阀者_FwtCoder31 分钟前
stagewise:让AI与代码编辑器无缝连接
前端·javascript·github
清沫33 分钟前
Cursor Rules 开发实践指南
前端·ai编程·cursor
江城开朗的豌豆38 分钟前
JavaScript篇:对象派 vs 过程派:编程江湖的两种武功心法
前端·javascript·面试
不吃糖葫芦340 分钟前
App使用webview套壳引入h5(二)—— app内访问h5,顶部被手机顶部菜单遮挡问题,保留顶部安全距离
前端·webview
菥菥爱嘻嘻1 小时前
JS手写代码篇---手写ajax
开发语言·javascript·ajax
江城开朗的豌豆1 小时前
JavaScript篇:字母侦探:如何快速统计字符串里谁才是'主角'?
前端·javascript·面试
kite01217 小时前
浏览器工作原理06 [#]渲染流程(下):HTML、CSS和JavaScript是如何变成页面的
javascript·css·html