96SEO 2026-04-28 08:08 22
又到了一年一度的“金三银四”,虽然招聘季的尾巴快抓不住了但hen多前端小伙伴的焦虑感却一点没少。特别是那些准备从初级向中高级进阶的朋友,面试中遇到JavaScript底层原理的拷问简直是家常便饭。这不Zui近有位在面试中屡次碰壁的主播,甚至一度想放弃治疗,直接转头去死磕React。但说实话,想玩转React,Vue或者Angular这些现代框架,JavaScript的根基打不牢,尤其是对this关键字的理解不够透彻,Zui后往往还是会在坑里爬不起来。

hen多初学者,甚至是有几年经验的开发者,各种花式调用方式往往会让我们晕头转向。今天我们就来彻底扒一扒this的老底,kankan它到底是怎么确定指向的。
我们要打破一个固有的思维定势。在Java、C++等静态语言中,this通常指向当前类的实例,非常老实。但在JavaScript里this的表现完全不同。它是在函数被调用时才发生的绑定,也就是说它的指向不取决于代码写在哪里而取决于函数在哪里被调用。
不管在什么地方使用this,它必然会指向某个对象。确定了第一点后也引出了一个问题,就是this使用的地方到底在哪里。在JavaScript语言之中,一切皆对象,这本来并不会让我们糊涂。但是JavaScript支持运行环境动态切换,也就是说this的指向是动态的,hen难事先确定到底指向哪个对象,这才是Zui让我们感到困惑的地方。
你Ke以把this想象成一个占位符,或者一个上下文环境的指针。当函数执行时解释器会问:“嘿,是谁在喊我?”喊它的那个对象,就是this指向的目标。
Zui常见的情况,就是函数独立调用。这时候,this通常会指向全局对象。这个全局对象就是window;而则是global。
举个例子:
function showAge {
console.log;
}
var age = 18;
showAge; // 输出 18
在这个例子里showAge是直接调用的,前面没有任何对象引导。所以JS引擎默认认为它是window调用的。因此,函数内部的this就指向了window,自然就Neng访问到全局变量age了。
但是这里有个大坑需要注意:严格模式。一旦开启了严格模式,这种默认绑定就会失效。独立调用的函数内部的
这是Zui符合我们直觉的一种情况。当一个函数被作为对象的方法调用时 kan个例子: 这里非常容易理解, 然而这种绑定方式非常脆弱。稍不注意, 为什么?因为 既然隐式绑定容易丢,那有没有办法硬性指定 这两个方法的作用是一样的,dou是改变函数执行时的
this将不再指向全局对象,而是指向
三、 隐式绑定:谁调用,就指向谁
'use strict';
function showAgeStrict {
console.log; // 输出 undefined
}
showAgeStrict;
this会自动指向那个对象。这就是所谓的“隐式绑定”。const person = {
name: 'Alice',
greet: function {
console.log;
}
};
person.greet; // 输出 "Hello, Alice"
greet方法是person对象调用的,所以其中的this指向person对象,this.name自然就是Alice。this就会“丢失”。比如我们将这个方法赋值给一个变量,或者作为回调函数传递:const fn = person.greet;
fn; // 此时输出 "Hello, " 或者报错,取决于是否有全局变量name
fn在调用时前面没有对象前缀,它变成了一个独立函数调用。这时候,规则就回到了“默认绑定”,this指向了全局对象。这就是hen多初学者在处理回调函数时容易踩的坑。this的指向呢?当然有。JavaScript提供了callapply和bind这三个强力工具,让我们Ke以随心所欲地控制this。this指向,并立即执行函数。唯一的区别在于传参的方式。call参数是一个一个传的。apply参数是以数组的形式传的。
function introduce {
console.log;
}
const alice = { name: 'Alice' };
const bob = { name: 'Bob' };
introduce.call; // 输出 "Hi, Alice!"
introduce.apply; // 输出 "Hello, Bob."
这就好比借花献佛。虽然introduce函数本身不属于alice或bob,但通过call或apply,我们强行让它在执行时认为自己是属于他们的。
bind方法和前两个有点不同。它不会立即执行函数,而是返回一个新的函数,并且这个新函数的this会被永久绑定到指定的对象上。无论之后怎么调用这个新函数,thisdou不会再变了。
const person = {
name: 'Ferrari',
sayBye: function {
console.log;
}
};
const car = { name: 'Toyota' };
// 创建一个新函数,this永久绑定到person
const boundFunc = person.sayBye.bind;
boundFunc; // 输出 "Bye from Ferrari"
// 即使尝试用call改变也无效
boundFunc.call; // 依然输出 "Bye from Ferrari"
在React类组件中,我们经常kan到this.handleClick = this.handleClick.bind这样的代码,就是为了防止事件回调时this丢失。
当我们使用new关键字来调用一个函数时这个函数就变成了构造函数。这时候,this的指向规则又变了。
使用new调用时会发生以下四步操作:
创建一个全新的空对象。
将这个新对象的原型链指向构造函数的prototype。
将构造函数内部的this指向这个新对象。
Ru果构造函数没有返回其他对象,则返回这个新对象。
function Car {
this.model = model;
}
const myCar = new Car;
console.log; // 输出 "Tesla"
在这里new Car就像是一个工厂,它把this指向了刚刚生产出来的myCar实例。这也是为什么我们Neng在构造函数里通过this.xxx给实例添加属性的原因。
ES6引入的箭头函数,在this的处理上是个异类。它没有自己的this。你听到没?它没有!
普通函数的this是在调用时确定的,而箭头函数的this是在它定义的时候就Yi经确定了。它的this指向的是它外层作用域的this。这就好比箭头函数是个“妈宝男”,它不自己找工作,而是直接继承老爸的家业。
const obj = {
name: 'Bob',
regularFunc: function {
setTimeout {
console.log; // 这里的this指向window,输出 undefined 或 window.name
}, 100);
},
arrowFunc: function {
setTimeout => {
console.log; // 这里的this继承自外层arrowFunc的this,即obj,输出 "Bob"
}, 100);
}
};
obj.regularFunc;
obj.arrowFunc;
这个特性在处理异步回调时简直不要太好用。以前我们经常需要var that = this;或者.bind来保存上下文,现在有了箭头函数,直接写进去就行了省心省力。
但是要注意,正因为箭头函数没有自己的this,所以你不Neng用callapplybind去改变它的this指向。对它来说这些方法统统无效。
在前端开发中,我们经常要给DOM元素绑定事件。这时候,this的指向也有它的规矩。
当事件被触发时事件处理函数中的this通常指向绑定事件的那个DOM元素。
const btn = document.querySelector;
btn.addEventListener {
console.log; // 指向 button 元素本身
this.style.backgroundColor = 'red';
});
但是Ru果你在这里使用了箭头函数,情况就不一样了。因为箭头函数继承外层this,而外层通常是全局对象,所以你就无法通过this操作当前按钮了。
btn.addEventListener => {
console.log; // 指向 window
// this.style.backgroundColor = 'red'; // 报错!
});
所以在DOM事件监听里用普通函数还是箭头函数,得kan你想不想操作当前元素。
八、 :如何一眼kan穿this?说了这么多,其实判断this指向是有优先级的。我们Ke以按照以下顺序来“排雷”:
new绑定函数是不是被new调用了?Ru果是this指向新创建的对象。
显式绑定有没有用callapplybind?Ru果是this指向指定的对象。
隐式绑定函数是不是作为对象的方法调用的?Ru果是this指向那个对象。
默认绑定Ru果以上dou不是那就是独立调用。在严格模式下是undefined,非严格模式下是全局对象。
当然别忘了箭头函数这个“不讲武德”的家伙,它直接无视上述规则,只kan外层作用域。
虽然this的指向规则kan起来繁琐,但只要理解了它的动态绑定机制,多写几个demo,多踩几次坑,自然就会形成肌肉记忆。当你Neng够不假思索地判断出一段代码中this指向谁的时候,恭喜你,你Yi经迈入了JavaScript这门语言的高阶门槛。那时候,再去面试,或者去学习React、Vue,你会发现一切dou变得豁然开朗了。
别再被this搞蒙圈了去代码里征服它吧!
作为专业的SEO优化服务提供商,我们致力于通过科学、系统的搜索引擎优化策略,帮助企业在百度、Google等搜索引擎中获得更高的排名和流量。我们的服务涵盖网站结构优化、内容优化、技术SEO和链接建设等多个维度。
| 服务项目 | 基础套餐 | 标准套餐 | 高级定制 |
|---|---|---|---|
| 关键词优化数量 | 10-20个核心词 | 30-50个核心词+长尾词 | 80-150个全方位覆盖 |
| 内容优化 | 基础页面优化 | 全站内容优化+每月5篇原创 | 个性化内容策略+每月15篇原创 |
| 技术SEO | 基本技术检查 | 全面技术优化+移动适配 | 深度技术重构+性能优化 |
| 外链建设 | 每月5-10条 | 每月20-30条高质量外链 | 每月50+条多渠道外链 |
| 数据报告 | 月度基础报告 | 双周详细报告+分析 | 每周深度报告+策略调整 |
| 效果保障 | 3-6个月见效 | 2-4个月见效 | 1-3个月快速见效 |
我们的SEO优化服务遵循科学严谨的流程,确保每一步都基于数据分析和行业最佳实践:
全面检测网站技术问题、内容质量、竞争对手情况,制定个性化优化方案。
基于用户搜索意图和商业目标,制定全面的关键词矩阵和布局策略。
解决网站技术问题,优化网站结构,提升页面速度和移动端体验。
创作高质量原创内容,优化现有页面,建立内容更新机制。
获取高质量外部链接,建立品牌在线影响力,提升网站权威度。
持续监控排名、流量和转化数据,根据效果调整优化策略。
基于我们服务的客户数据统计,平均优化效果如下:
我们坚信,真正的SEO优化不仅仅是追求排名,而是通过提供优质内容、优化用户体验、建立网站权威,最终实现可持续的业务增长。我们的目标是与客户建立长期合作关系,共同成长。
Demand feedback