真的!真的就一句话就能明白this指向问题

就一句话:函数也是对象

为什么这个认知能帮我们理解this指向问题?且由我来为客官们解读。

第一部分:函数作为对象的本质

函数是特殊的对象

既然函数是对象 ,那么函数也就有属性方法

代码示例:

javascript 复制代码
// 函数是对象,有属性和方法
function myFunction() {
    console.log("Hello");
}

// 函数对象的属性
console.log(myFunction.name);        // "myFunction"
console.log(myFunction.length);      // 0 (参数个数)
console.log(myFunction.prototype);   // 原型对象
console.log(typeof myFunction);      // "function"

那么就知道函数的属性可以存储数据与函数的方法可以控制函数的行为。

函数对象的特殊方法

函数对象的原型链上有callapplybind等方法,这些方法能控制函数执行时的this 指向,说明了this的指向是可以被控制的。

代码示例:

javascript 复制代码
function test() {
    console.log(this.name);
}

// 函数对象有三个重要方法
test.call(obj);    // 立即执行,this 指向 obj
test.apply(obj);   // 立即执行,this 指向 obj  
test.bind(obj);    // 返回新函数,this 永久绑定到 obj

第二部分:this指向的确定

this指向有四种情况,分别为普通函数调用方法调用构造函数调用间接调用

情况1: 普通函数调用

javascript 复制代码
function func1() {
    console.log(this); //this 指向window (非严格模式)
}
func1(); // 独立调用

情况2: 方法调用

javascript 复制代码
var obj = {
    method: function() {
        console.log(this); // this 指向obj
    }
};
obj.method(); // 通过对象调用

情况3: 构造函数调用

javascript 复制代码
function Person(name) {
    this.name = name; // this 指向新创建的对象
}
var person = new Person("John");

情况4: 间接调用

javascript 复制代码
function func2() {
    console.log(this);
}
func2.call(obj); // this 指向 obj

this的指向取决于函数的调用方式,不同方式会产生不同的this指向,说明了this是动态的,不是静态的。

少侠请听题:

判断一下会输出什么?

javascript 复制代码
var name = "The Window"
var object = {
    name: "My object",
    getNameFunc: function() {
        return function() {
            return this.name; 
        };
    }
};
console.log(object.getNameFunc()());

答案是The Window

Why?因为是独立调用 ,返回的是一个立即执行函数,过程可以拆解为 var returnedFunc = object.getNameFunc()先获取到了函数,再执行returnedFunc()独立调用this 指向了window。问题的根源其实就是返回的函数失去了原来的对象上下文

那我们要输出My object怎么办?

方法一: 使用闭包来捕获变量

javascript 复制代码
var name = "The Window"
var object = {
    name: "My object",
    getNameFunc: function() {
    var that = this; // 添加这里
        return function() {
            return that.name; 
        };
    }
};

分析: object.getNameFunc()执行时,this指向了object,因为将this赋给了that,将object的引用保存到了that,返回内部函数,该函数形成了闭包,能够访问that,内部函数被独立调用 的时候,this指向了window,但that仍然指向object,于是就能够输出My object

方法二: 使用箭头函数

javascript 复制代码
var name = "The Window"
var object = {
    name: "My object",
    getNameFunc: function() {
        return () => {
            return this.name; 
        };
    }
};

分析: object.getNameFunc() 执行时,this 指向 object,由于箭头函数没有自己的this,定义时this就确定了,不会在调用时改变(词法作用域 ),this会继承所在作用域(即 getNameFunc)的 this,指向 object。于是也能够输出My object

方法三: 使用bind方法

javascript 复制代码
var name = "The Window"
var object = {
    name: "My object",
    getNameFunc: function() {
        return function() {
            return this.name;
        }.bind(this); // 显式绑定 this
    }
};

总结

函数作为对象的特性(有方法、有属性、可以形成闭包)提供了多种解决 this 指向问题的工具和方法。

相关推荐
weixin_382395237 小时前
为小工厂量身打造:本地部署的物料管理系统带缺料计算
前端·制造
__zRainy__7 小时前
解决pnpm v10+不自动构建
前端·pnpm·工程化
猫猫不是喵喵.8 小时前
Vue3 Props 属性
前端·javascript·vue.js
醉城夜风~9 小时前
CSS元素显示模式(display)
前端·css
AI大模型-小华9 小时前
Codex 三方充值快速入门指南
java·前端·数据库·chatgpt·ai编程·codex·chatgpt pro
做前端的娜娜子12 小时前
同一链接实现 PC Web 与移动 H5 自适应
前端·掘金·金石计划
小帅不太帅12 小时前
架构没变、规模没变,DeepSeek V4 Flash 正式版凭什么暴涨 47 分?
前端·aigc·deepseek
jarvisuni12 小时前
DeepSeekFlash前端依旧拉垮,而且变慢了很多!
前端·javascript·算法
卷福同学14 小时前
AI编程出海第二步:验证关键词能否做站
前端·人工智能·后端