likes
comments
collection
share

JavaScript 细节(一)

作者站长头像
站长
· 阅读数 5

1.关于promise

一个经典的promise用法如下:

const myPromise = new Promise((resolve, reject) => {
  // 异步操作
  if (/* 操作成功 */) {
    resolve('成功的结果');
  } else {
    reject('失败的原因');
  }
});

myPromise
  .then((result) => {
    console.log(result); // 处理成功的结果
  })
  .catch((error) => {
    console.error(error); // 处理失败的原因
  })
  .finally(() => {
    // 无论成功还是失败都会执行
  });

值得一提的是,这里的resolvereject是由JavaScript引擎提供的两个函数,coder只需要调用它们即可。下面是它们具体的作用:

  • resolve函数:当异步操作成功完成时,resolve函数被调用。它将Promise的状态从“等待”(pending)改变为“已完成”(fulfilled)。调用resolve时传递的任何值都会成为Promise成功处理的结果,这个值会被传递给.then()方法中注册的回调函数。
  • reject函数:当异步操作失败或出现错误时,reject函数被调用。它将Promise的状态从“等待”(pending)改变为“已拒绝”(rejected)。调用reject时传递的错误信息会被传递给.catch()方法中注册的回调函数。

2.this和self有什么区别

在JavaScript中,thisself通常指向不同的对象,尽管它们在某些情况下可能指向相同的全局对象。

  • this关键字this是一个关键字,它在函数执行时被自动设置,指向调用函数的上下文对象。在全局作用域中,非严格模式下的this指向全局对象(浏览器中的window),而在严格模式下,this的值为undefined。在对象的方法中,this通常指向调用该方法的对象。在构造函数中,this指向新创建的实例。
  • self变量self通常用于Web Workers中,它是一个全局变量,指向全局上下文,这在Web Workers中就是WorkerGlobalScope。在浏览器环境中,self通常等同于window对象,因此在全局作用域中selfthis是相同的。但是,self在函数内部不会改变,它始终指向全局对象,而this的值会根据函数的调用方式而变化。

说到this,正好可以提及一下bind函数, JavaScript的bind函数用于创建一个新的函数,这个新函数会将this关键字绑定到指定的对象上。当绑定函数被调用时,它的this值将被设置为bind时传递的第一个参数。这使得你可以确保无论函数如何被调用,this都指向正确的对象。 因此如果不使用bind函数,可能会遇到this上下文不正确的问题。这通常发生在以下情况:

  1. 回调函数中:当将对象的方法作为回调函数传递时,如果不绑定this,方法内部的this可能不会指向原始对象,而是指向全局对象或undefined
  2. 事件处理器中:在事件监听器中,如果不使用bindthis通常指向触发事件的元素,而不是定义事件处理器的对象。
  3. setTimeout/setInterval中:在这些函数中使用对象的方法时,如果不绑定,this将指向全局对象或undefined。如以下的例子:
function myFunction() {
  console.log(this);
}

// 在全局作用域中调用myFunction,this指向全局对象
myFunction(); // 输出: Window

// 使用setTimeout调用myFunction,this仍然指向全局对象
setTimeout(myFunction, 1000); // 输出: Window(在1秒后)

  1. 高阶函数中:当在高阶函数(如mapfilter等)中使用对象的方法时,如果不绑定,this可能不会指向预期的对象。

除了设置thisbind还可以让你预设函数参数,这些参数会在绑定函数被调用时作为原始函数的前几个参数传递。这对于部分应用函数非常有用,可以减少需要手动传递的参数数量。不过ES6之后有了默认参数值,这个作用倒是没这么大了。

最后这里是一个bind的简单示例:

function greet(greeting, punctuation) {
  console.log(greeting + ', ' + this.name + punctuation);
}

const person = {
  name: 'John'
};

const greetJohn = greet.bind(person, 'Hello');
greetJohn('!'); // 输出: "Hello, John!"

3.JS赋值语句有返回值,即等号右边的值

console.log(a=12) // 输出 12

4.undefined vs null

在JavaScript中,nullundefined都表示没有值,但它们用于不同的场景:

  • undefined:当变量被声明但没有被赋值时,它的值就是undefined。这也是函数没有返回值时的默认值。undefined是一个原始数据类型。
  • nullnull是一个表示无任何对象值的意图性赋值。它通常用于明确指示变量或对象属性应该没有值。null也是一个原始数据类型。

两者的主要区别在于:

  • undefined表示变量已声明但未赋值。
  • null是一个明确赋予变量的值,表示变量不应该有值。

在比较时,nullundefined在非严格比较(==)中是相等的,但在严格比较(===)中不相等,因为它们是不同的类型。 此外可以对 undefined 赋值,但是不能对null赋值,否则返回 Uncaught SyntaxError: Invalid left-hand side in assignment.

5.关于函数

JavaScript 中的函数是一种特殊类型的对象,被称为函数对象。函数对象包含一个字符串,其中保存了函数的实际代码,也就是函数体。这段代码实际上就是一个字符串。 通过调用函数对象的toString方法可以获取函数代码,如下所示。

function getABird(){ return { fly: true }}
//输出 function getABird(){ return { fly: true }}
console.log(getABird)

不过对于内置函数,比如setTimeout则不然。

// 输出 function setTimeout() { [native code] }
console.log(setTimeout)

这是因为JavaScript 中的内置函数(也称为原生函数)是由 JavaScript 引擎实现的,通常是用 C++ 编写的。这些函数在 JavaScript 运行时中作为二进制代码存在,而不是作为文本代码。