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

JavaScrip中的this、作用域代码输出题

一、函数调用中的 this

var name = "Global";function printName() {console.log(this.name);
}var obj = {name: "Object",printName: printName
};printName();         // 输出是什么?
obj.printName();     // 输出是什么?
  • printName();

    • 在全局环境中直接调用函数,this 默认指向全局对象(浏览器中是 window,Node.js 中是 global)。
    • this.name 等同于 window.name,所以输出 "Global"
  • obj.printName();

    • 函数作为对象的方法被调用,this 指向调用该方法的对象 obj
    • this.name 等同于 obj.name,所以输出 "Object"

二、this 与箭头函数

var name = "Global";var obj = {name: "Object",regularFunc: function() {console.log(this.name);},arrowFunc: () => {console.log(this.name);}
};obj.regularFunc();  // 输出是什么?
obj.arrowFunc();    // 输出是什么?
  • obj.regularFunc();

    • 普通函数,this 指向调用者 obj
    • 输出 "Object"
  • obj.arrowFunc();

    • 箭头函数,this 不绑定到 obj而是继承自外层作用域。
    • 在全局作用域中,this 指向全局对象,this.name 等同于 window.name,输出 "Global"

三、作用域与闭包

for (var i = 0; i < 3; i++) {setTimeout(function() {console.log(i);}, 1000);
}
以上代码在一秒后会输出什么?
  • setTimeout 的回调函数在事件队列中等待,循环结束后才执行。
  • 此时,i 已经变为 3,所以会输出三次 3(因为var i是全局作用变量,每次设定回调函授,执行时i已经到达3)
如何修复问题:

方法一:使用 let 替代 var

for (let i = 0; i < 3; i++) {setTimeout(function() {console.log(i);}, 1000);
}
  • let 声明的变量具有 块级作用域,在每次循环中,i 都是一个新的变量。

  • setTimeout 回调函数中的 i 会各自引用循环中当前的 i

  • 输出结果:

    • 0

    • 1

    • 2

方法二:使用立即执行函数表达式(IIFE)创建闭包
for (var i = 0; i < 3; i++) {(function(j) {setTimeout(function() {console.log(j);}, 1000);})(i);
}
  • 使用 IIFE(Immediately Invoked Function Expression)创建了一个新的作用域。

  • 将当前的 i 值作为参数 j 传递给 IIFE,j 是 IIFE 内部的局部变量。

  • setTimeout 回调函数中的 console.log(j); 会引用 IIFE 中的 j,即当前循环中的 i 值。

  • 输出结果

    • 0

    • 1

    • 2

方法三:使用 forEach 等迭代方法
[0, 1, 2].forEach(function(i) {setTimeout(function() {console.log(i);}, 1000);
});
  • forEach 的回调函数中,i 是每次迭代的当前元素

  • i 在每次迭代中都是一个新的变量,不会相互干扰。

  • 输出结果:

    • 0

    • 1

    • 2

四、this 与函数内的函数

var length = 10;function fn() {console.log(this.length);
}var obj = {length: 5,method: function(fn) {fn();                   // 输出是什么?  10arguments[0]();         // 输出是什么?  1}
};obj.method(fn);
arguments[0]()解释:
  • arguments 对象是函数内部的一个局部变量,包含了函数调用时的所有参数。
  • arguments.length:表示传递给函数的参数数量。
  • arguments 是一个类数组对象,具有索引和 length 属性。
  • arguments[0] 就是传入的 fn 函数。
  • arguments 对象的 length 属性表示传入参数的数量,此处为 1
  • 相当于方法调用arguments 对象调用其属性 0 上的函数。
  • 等价于arguments[0].call(arguments);

五、对象方法中的 this 绑定

var obj = {name: "Alice",getName: function() {return this.name;}
};var getName = obj.getName;console.log(getName());     // 输出是什么? undefined
console.log(obj.getName()); // 输出是什么? Alice
  • getName();

    • 函数被赋值给变量并在全局环境中调用,this 指向全局对象。
    • 如果全局对象没有 name 属性,输出 undefined
  • obj.getName();

    • 方法作为对象的属性调用,this 指向 obj
    • 输出 "Alice"

六、构造函数与原型链中的 this

function Person(name) {this.name = name;
}Person.prototype.getName = function() {return this.name;
};var person = new Person("Bob");console.log(person.getName()); // 输出是什么?
  • Person 是构造函数,new 关键字创建一个新的对象,this 指向新创建的对象
  • person.getName() 中,this 指向 person 对象。
  • 输出 "Bob"

​​​​​​​


http://www.mrgr.cn/news/29181.html

相关文章:

  • 深度解析 Linux 系统下的 top 命令
  • idea 删除本地分支后,弹窗 delete tracked brank
  • 万字长文解读深度学习——ViT、ViLT、DiT
  • odoo17 owl 前端 顶部导航栏右侧添加自定义按钮
  • 【FreeRL】MAPPO的简单复现
  • 自動換IP為什麼會不穩定?
  • 深入理解Redis:缓存穿透、缓存击穿、缓存雪崩及双写一致性
  • 【乐企-业务篇】乐企前置条件规则枚举
  • 基于Qt的串口调试工具串口常见问题
  • NASA:ATLAS/ICESat-2 L3 A陆地冰高度,版本6
  • Java应用的数据库连接池连接回收策略
  • 使用MongoDB存储和查询数据的Python函数实现
  • Java | Leetcode Java题解之第413题等差数列划分
  • 数据权限的设计与实现系列9——前端筛选器组件Everright-filter集成框架开发2
  • 输煤传送带异物识别检测数据集 yolo数据集 2400张
  • 创建自定义LLM类:更灵活地使用你的语言模型
  • 通信工程学习:什么是OLT光线路终端
  • 在Unity UI中实现UILineRenderer组件绘制线条
  • 【强化学习】如何在不提供标签的情况下通过试错的方式来学习?
  • java四种内置线程池介绍
  • Python面试宝典第49题:字符串压缩
  • DigiDNA推出iMazing 3.0.4,支持Apple Vision Pro
  • 【自动驾驶】决策规划算法(一)决策规划仿真平台搭建 | Matlab + Prescan + Carsim 联合仿真基本操作
  • 用Python实现时间序列模型实战——Day 24: 时间序列中的贝叶斯方法
  • Rust GUI框架Tauri V1 入门
  • C# 链表排序之归并排序