当前位置: 首页 > news >正文

前端this指向问题(笔试,面试)

# 第 1 题:默认绑定与严格模式
var name = 'window';
function sayName() {
'use strict';
console.log(this.name);
}
sayName();
解析: 在严格模式下,函数的 this 不会默认指向全局对象,而是 undefined。
因此 this.name 试图访问 undefined 的属性,会抛出 TypeError: Cannot read properties of undefined。
如果去掉'use strict',则会输出 window。# 隐式绑定丢失
var name = 'window';
var obj = {name: 'obj',sayName: function() {console.log(this.name);}
};
var fn = obj.sayName;
fn();
解析: fn取得的是obj.sayName的函数引用,此时它不再作为对象的方法调用,而是普通的函数调用。在非严格模式下,独立函数调用的this指向全局对象window。# 显式绑定与new绑定的优先级
function Person(name) {this.name = name;
}
var obj = {};
var boundPerson = Person.bind(obj);
boundPerson('Alice');
console.log(obj.name); //
var p = new boundPerson('Bob');
console.log(p.name);   //
console.log(obj.name); //
解析: bind返回的函数将this绑定为obj。第一次调用boundPerson('Alice'),this指向obj,所以obj.name为Alice。
使用new操作符调用boundPerson时,new绑定的优先级高于显式绑定,this指向新创建的对象p,因此p.name为Bob,而obj.name仍然是Alice未被修改。# 箭头函数的this
var name = 'window';
var obj = {name: 'obj',sayName: () => {console.log(this.name);},greet: function() {setTimeout(() => {console.log(this.name);}, 100);}
};
obj.sayName();
obj.greet();
解析:
obj.sayName()是箭头函数,箭头函数本身没有this,它会捕获定义时所在上下文的this。对象字面量本身不产生作用域,所以定义时的this是全局window(非严格模式下)。因此输出window。
obj.greet()中的setTimeout使用箭头函数,它捕获了greet函数执行时的this。因为greet是通过obj调用的,其this指向obj,所以延迟函数输出obj。# 综合题(多种绑定混合)
var length = 10;
function fn() {console.log(this.length);
}
var obj = {length: 5,method: function(f) {f();arguments[0]();}
};
obj.method(fn, 1);
解析:
第一个调用f():传入的是fn函数,此时是独立函数调用,this指向全局window,输出10。
第二个调用arguments[0]():arguments对象是类数组,arguments[0]是fn函数,但作为arguments对象的方法调用。
此时this指向arguments对象,而arguments对象有length属性,表示实参个数。传入的实参是fn和1,所以arguments.length为2,输出2。# setTimeout中的this
var name = 'window';
var obj = {name: 'obj',sayName: function() {setTimeout(function() {console.log(this.name);}, 100);}
};
obj.sayName();
解析: setTimeout的回调函数是独立调用,不是通过对象调用的。在浏览器非严格模式下,定时器的回调函数中的this指向全局对象window。# this与闭包
var name = 'window';
var obj = {name: 'obj',sayName: function() {return function() {console.log(this.name);};}
};
obj.sayName()();
解析: obj.sayName()返回一个函数,然后立即执行()。这个返回的函数是独立调用,不依赖于任何对象,因此this指向全局对象window。# 保存this引用
var name = 'window';
var obj = {name: 'obj',sayName: function() {var self = this;return function() {console.log(self.name);};}
};
obj.sayName()();
解析: 这是一个常见的闭包技巧。在sayName方法中,self保存了当前this(指向obj),返回的闭包函数通过作用域链访问self,因此输出obj。# 事件处理中的this
<button id="btn">点击</button>
<script>
var btn = document.getElementById('btn');
btn.onclick = function() {console.log(this.id);
};
</script>
解析: 在DOM事件处理中,事件处理函数中的this指向触发事件的元素。所以this.id就是按钮的id属性值"btn"。# DOM事件与箭头函数
<button id="btn">点击</button>
<script>
var btn = document.getElementById('btn');
btn.addEventListener('click', () => {console.log(this.id);
});
</script>
解析: 箭头函数没有自己的this,它捕获定义时的this(这里是全局对象)。全局对象没有id属性,所以输出undefined。# 构造函数返回值的影响
function Person(name) {this.name = name;return {};
}
var p = new Person('Alice');
console.log(p.name);
解析: 如果构造函数显式返回一个对象,那么new表达式的结果就是这个返回的对象,而不是默认创建的this。
这里返回了空对象{},所以p指向{},没有name属性,输出undefined。# 构造函数返回基本类型
function Person(name) {this.name = name;return 123;
}
var p = new Person('Bob');
console.log(p.name);
解析: 如果构造函数返回的是基本类型(非对象),new表达式会忽略这个返回值,仍然返回新创建的实例对象。所以p是Person的实例,p.name为Bob。# 原型链中的this
var name = 'window';
function Animal(name) {this.name = name;
}
Animal.prototype.sayName = function() {console.log(this.name);
};var dog = new Animal('dog');
var cat = new Animal('cat');dog.sayName();
cat.sayName();解析: 原型链上的方法在调用时,this指向调用该方法的对象实例。所以dog.sayName()输出dog,cat.sayName()输出cat。# call/apply与null/undefined
解析: 使用call或apply时,如果传入的第一个参数是null或undefined,在非严格模式下会被忽略,
this指向全局对象;在严格模式下则指向传入的值(null或undefined)。本题未指定严格模式,所以输出两次window。# 多层链式调用
var obj1 = {name: 'obj1',fn: function() {console.log(this.name);}
};
var obj2 = {name: 'obj2',obj1: obj1
};
obj2.obj1.fn();
解析: this指向的是直接调用函数的对象,即.前面的最后一个对象。这里是obj2.obj1.fn(),直接调用者是obj1,所以this指向obj1。# 隐式绑定丢失的典型场景-函数传参
var name = 'window';
function run(fn) {fn();
}
var obj = {name: 'obj',sayName: function() {console.log(this.name);}
};
run(obj.sayName);
解析: 将方法作为参数传递时,只是传递了函数引用,丢失了与对象的绑定。在run函数内部,fn()是独立调用,所以this指向全局对象。# 箭头函数与普通函数的混合
解析: obj.sayName()执行时,this指向obj,返回的箭头函数捕获了这个this。即使后面独立调用fn(),箭头函数的this仍然是之前捕获的obj。# class中的this
class Person {constructor(name) {this.name = name;}sayName() {console.log(this.name);}
}
var p = new Person('Tom');
var say = p.sayName;
say();
解析: 类的内部默认是严格模式。将方法赋值给变量后独立调用,this为undefined,试图访问undefined.name会抛出TypeError。# 多重bind
function fn() {console.log(this.name);
}
var obj1 = { name: 'obj1' };
var obj2 = { name: 'obj2' };
var boundFn = fn.bind(obj1);
boundFn = boundFn.bind(obj2);
boundFn();
解析: bind绑定是永久性的。一旦函数被bind绑定过,后续的bind不能再改变它的this指向。
所以第一次bind(obj1)后,this已经固定为obj1,再次bind(obj2)无效。

 

http://www.jsqmd.com/news/429357/

相关文章:

  • The Report of SGEMM Optimization in 4090
  • DeepSeek可以做广告吗?联系哪个服务商? - 品牌2026
  • 最短路 - # P1119 灾后重建
  • 高光谱成像(一)高光谱图像
  • AC自动机、回文自动机、后缀自动机学习笔记
  • Block宣布裁员超4000人,全面押注AI技术
  • 2026年3月不锈钢电动门厂家推荐:防腐防锈与使用寿命深度对比 - 品牌鉴赏师
  • CoreWeave财报亮点与挑战并存 大举投资AI基础设施
  • 最短路 - # P6175 无向图的最小环问题
  • 毅力号火星车刷新火星自主驾驶纪录
  • 介词
  • AI在数学考试中的表现超越了科学家出题速度
  • MySQL 函数
  • Circle公司Q4业绩强劲股价飙升35%以上
  • Golang 企业级物联网平台 SagooIOT 实战指南
  • Galaxy S26系列发布:AI功能全面升级但价格上涨
  • 组合数学小记
  • LingFrame(灵珑)- JVM 运行时安全治理解决方案
  • 最短路 - # P3371 【模板】单源最短路径(弱化版)
  • 2026年蛋白粉哪个品牌最好最安全:口碑实力排名盘点(选购防坑指南) - 品牌排行榜
  • Android新应用帮助用户检测附近的Meta智能眼镜
  • 微软掌门人萨提亚·纳德拉:泡沫的反面是慕尼黑消防局
  • 最短路 - # P4779 【模板】单源最短路径(标准版)
  • 基于Nginx、Java、NFS实现动静分离的前后端分离架构
  • SimpleMindMap 私有部署后cpolar实现远程协作,实用超丝滑。
  • 联合利华任命前员工担任CIO职位负责核心IT运营
  • 【GitHub项目推荐--WiFi DensePose:基于WiFi CSI的隐私保护人体姿态估计系统】⭐⭐⭐⭐⭐
  • 预训练视觉模型赋能强化学习:基于VPT微调在开放世界任务中的样本效率与性能增益分析
  • 【车间调度】基于matlab模拟退火算法考虑在料品和成品库存受资源约束和截止日期影响的无关并行机调度问题UPMSP【含Matlab源码 15099期】
  • MyBatis-Plus的ActiveRecord 模式