每日JS面试分享(6)

本文介绍了JavaScript中this的关键字指向,包括全局作用域、方法调用、构造函数、显式绑定、箭头函数等场景。同时讨论了检测数组的多种方法,如instanceof、Array.isArray()、Object.prototype.toString.call()等,以及它们的优缺点。此外,还解释了函数柯里化的概念,并指出setInterval时间不准确的原因及解决方案。
摘要由CSDN通过智能技术生成

1、说一下this关键字的指向

1、全局作用域或普通函数调用:

当在全局作用域或通过普通函数调用使用 this 时,它通常指向全局对象(在浏览器中为 window,在 Node.js 中为 global)。

function globalFunction() {
  console.log(this); // 在浏览器中指向 window,Node.js 中指向 global
}
globalFunction();

2、方法调用:

当在对象的方法中使用 this 时,它通常指向调用该方法的对象。

const obj = {
  foo: function () {
    console.log(this); // 指向 obj
  },
};
obj.foo();

3、构造函数调用:

当在构造函数中使用 this 时,它指向新创建的实例对象。

function Person(name) {
  this.name = name;
}
const person = new Person('John');
console.log(person.name); // 输出 "John"

4、显式绑定:

当使用 callapplybind 方法显式设置函数调用的上下文时,this 将指向传递给这些方法的第一个参数。

function greet() {
  console.log(`Hello, ${this.name}!`);
}
const alice = { name: 'Alice' };
const bob = { name: 'Bob' };
greet.call(alice); // 输出 "Hello, Alice!"
greet.call(bob); // 输出 "Hello, Bob!"

5、箭头函数:

箭头函数没有自己的 this 值。在箭头函数中使用 this 时,它会从包含箭头函数的最近的非箭头函数作用域中继承 this 值。

const obj = {
  foo: function () {
    const bar = () => {
      console.log(this); // 指向 obj,因为箭头函数继承了最近的非箭头函数作用域的 this 值
    };
    bar();
  },
};
obj.foo();

6、事件处理程序:

在 DOM 事件处理程序中,this 通常指向触发事件的元素。例如,当用户点击一个按钮时,this 将指向被点击的按钮。

<button id="myButton">Click me</button>
<script> document.getElementById('myButton').addEventListener('click', function () {
    console.log(this); // 指向被点击的按钮元素
  });
</script>

7、类方法:

在 ES6 类的方法中使用 this 时,它指向调用该方法的实例。这与普通对象方法的行为类似。

class Person {
  constructor(name) {
    this.name = name;
  }
  greet() {
    console.log(`Hello, ${this.name}!`);
  }
}
const alice = new Person('Alice');
alice.greet(); // 输出 "Hello, Alice!"

8、使用 setTimeoutsetInterval

setTimeoutsetInterval 的回调函数中使用 this 时,它通常指向全局对象

function MyObject() {
  this.value = 'Hello';
  setTimeout(function () {
    console.log(this.value); // undefined,因为此时的 this 指向全局对象
  }, 1000);
}
const obj = new MyObject();

2、判断数组的方法以及优缺点?

1、instanceof 操作符

const arr = [];
console.log(arr instanceof Array); // 输出 true

优点:

  • 简单易用,可读性好。

缺点:

  • 在涉及多个全局执行上下文(例如来自不同 iframe 的对象)时,可能会失效。这是因为每个全局执行上下文都有其自己的 Array 构造函数,instanceof 会检查对象是否是当前执行上下文中 Array 的实例。

2、 Array.isArray() 方法(推荐)

const arr = [];
console.log(Array.isArray(arr)); // 输出 true

优点:

  • 可靠性更高,能正确处理多个全局执行上下文的情况。
  • 简单易用,可读性好。

缺点:

  • 在 ECMAScript 5 之前的浏览器(如 IE8 及更早版本)中不可用,需要进行 polyfill。

3、 使用 Object.prototype.toString.call() 方法

const arr = [];
console.log(Object.prototype.toString.call(arr) === '[object Array]'); // 输出 true

优点:

  • 能在所有 JavaScript 环境中可靠地工作,包括旧的浏览器。
  • 能正确处理多个全局执行上下文的情况。

缺点:

  • 代码较长,可读性较差。

4、使用 constructor 属性

const arr = [];
console.log(arr.constructor === Array); // 输出 true

优点:

  • 简单易用,可读性好。

缺点:

  • 如果某个对象的原型链中 constructor 属性被篡改,此方法可能失效。
  • 在涉及多个全局执行上下文的情况下,可能会失效。

5、 使用 Array.prototype.isPrototypeOf() 方法(不推荐)

const arr = [];
console.log(Array.prototype.isPrototypeOf(arr)); // 输出 true

使用 Array.prototype.isPrototypeOf() 方法判断一个变量是否为数组的优缺点如下:

优点:

  • 可以在多个全局执行上下文(例如不同的 iframe)中正常工作,因为它仅检查对象的原型链是否包含 Array.prototype

缺点:

  • 不如其他方法简洁明了,可读性较差。
  • 在某些情况下,例如当数组的原型链被篡改时,此方法可能会产生错误的结果。

3、什么是函数柯里化?

柯里化是将一个接受多个参数的函数转换为一系列接受单一参数的函数的过程。换句话说,柯里化是把一个多参数函数转化为一连串的一元函数(每个函数只接受一个参数)。

假设我们有一个普通的多参数函数 add

function add(x, y) {
  return x + y;
}
console.log(add(1, 2)); // 输出 3

现在,我们将 add 函数柯里化:

function curryAdd(x) {
  return function(y) {
    return x + y;
  };
}
const add1 = curryAdd(1); // 返回一个新函数,该函数将 1 作为第一个参数
console.log(add1(2)); // 输出 3

在上述示例中,我们将 add 函数转换为柯里化版本的 curryAdd 函数。curryAdd 函数接受一个参数 x,并返回一个新函数,该新函数接受另一个参数 y。调用这个新函数时,它将返回 xy 的和。

4、setInterval时间为什么不准确?怎么解决?

setInterval时间不准确的原因是,它的回调函数并不是到时后立即执行,而是等系统计算资源空闲下来后才会执行。而下一次触发时间则是在setInterval回调函数执行完毕之后才开始计时。所以如果setInterval内执行的计算过于耗时,或者有其他耗时任务在执行,setInterval的计时会越来越不准,延迟很厉害。

解决的方法是,使用setTimeout代替setInterval,并且每次执行结束后,根据误差值动态调整下一次执行的间隔时间。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值