JavaScript 细节(一)
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(() => {
// 无论成功还是失败都会执行
});
值得一提的是,这里的resolve和reject是由JavaScript引擎提供的两个函数,coder只需要调用它们即可。下面是它们具体的作用:
resolve函数:当异步操作成功完成时,resolve函数被调用。它将Promise的状态从“等待”(pending)改变为“已完成”(fulfilled)。调用resolve时传递的任何值都会成为Promise成功处理的结果,这个值会被传递给.then()方法中注册的回调函数。reject函数:当异步操作失败或出现错误时,reject函数被调用。它将Promise的状态从“等待”(pending)改变为“已拒绝”(rejected)。调用reject时传递的错误信息会被传递给.catch()方法中注册的回调函数。
2.this和self有什么区别
在JavaScript中,this和self通常指向不同的对象,尽管它们在某些情况下可能指向相同的全局对象。
this关键字:this是一个关键字,它在函数执行时被自动设置,指向调用函数的上下文对象。在全局作用域中,非严格模式下的this指向全局对象(浏览器中的window),而在严格模式下,this的值为undefined。在对象的方法中,this通常指向调用该方法的对象。在构造函数中,this指向新创建的实例。self变量:self通常用于Web Workers中,它是一个全局变量,指向全局上下文,这在Web Workers中就是WorkerGlobalScope。在浏览器环境中,self通常等同于window对象,因此在全局作用域中self和this是相同的。但是,self在函数内部不会改变,它始终指向全局对象,而this的值会根据函数的调用方式而变化。
说到this,正好可以提及一下bind函数,
JavaScript的bind函数用于创建一个新的函数,这个新函数会将this关键字绑定到指定的对象上。当绑定函数被调用时,它的this值将被设置为bind时传递的第一个参数。这使得你可以确保无论函数如何被调用,this都指向正确的对象。
因此如果不使用bind函数,可能会遇到this上下文不正确的问题。这通常发生在以下情况:
- 回调函数中:当将对象的方法作为回调函数传递时,如果不绑定
this,方法内部的this可能不会指向原始对象,而是指向全局对象或undefined。 - 事件处理器中:在事件监听器中,如果不使用
bind,this通常指向触发事件的元素,而不是定义事件处理器的对象。 - setTimeout/setInterval中:在这些函数中使用对象的方法时,如果不绑定,
this将指向全局对象或undefined。如以下的例子:
function myFunction() {
console.log(this);
}
// 在全局作用域中调用myFunction,this指向全局对象
myFunction(); // 输出: Window
// 使用setTimeout调用myFunction,this仍然指向全局对象
setTimeout(myFunction, 1000); // 输出: Window(在1秒后)
- 高阶函数中:当在高阶函数(如
map、filter等)中使用对象的方法时,如果不绑定,this可能不会指向预期的对象。
除了设置this,bind还可以让你预设函数参数,这些参数会在绑定函数被调用时作为原始函数的前几个参数传递。这对于部分应用函数非常有用,可以减少需要手动传递的参数数量。不过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中,null和undefined都表示没有值,但它们用于不同的场景:
undefined:当变量被声明但没有被赋值时,它的值就是undefined。这也是函数没有返回值时的默认值。undefined是一个原始数据类型。null:null是一个表示无任何对象值的意图性赋值。它通常用于明确指示变量或对象属性应该没有值。null也是一个原始数据类型。
两者的主要区别在于:
undefined表示变量已声明但未赋值。null是一个明确赋予变量的值,表示变量不应该有值。
在比较时,null和undefined在非严格比较(==)中是相等的,但在严格比较(===)中不相等,因为它们是不同的类型。
此外可以对 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 运行时中作为二进制代码存在,而不是作为文本代码。
转载自:https://juejin.cn/post/7351581179018051618