真的!真的就一句话就能明白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 指向问题的工具和方法。

相关推荐
AI视觉网奇2 小时前
rknn yolo11 推理
前端·人工智能·python
gplitems1232 小时前
Gunslinger – Gun Store & Hunting WordPress Theme: A Responsible
开发语言·前端·javascript
Winson℡5 小时前
React Native 中的 useCallback
javascript·react native·react.js
wyzqhhhh5 小时前
less和sass
前端·less·sass
Nan_Shu_6146 小时前
学习:uniapp全栈微信小程序vue3后台-额外/精彩报错篇
前端·学习·微信小程序·小程序·uni-app·notepad++
excel7 小时前
Vue3 中的双向链表依赖管理详解与示例
前端
谢尔登7 小时前
【Nest】基本概念
javascript·node.js·express
前端小白从0开始8 小时前
Chrome DevTools高级用法:性能面板内存泄漏排查
前端·chrome·chrome devtools
EveryPossible8 小时前
带有渐变光晕
前端·javascript·css
jojo是只猫8 小时前
Vue 3 开发的 HLS 视频流播放组件+异常处理
前端·javascript·vue.js