JSAPI
JavaScript 标准内置对象
Object
Object.fromEntries
note
Object.fromEntries()
方法接收一个键值对的列表参数,并返回一个带有这些键值对的新对象。这个迭代参数应该是一个能够实现@@iterator
方法的的对象,返回一个迭代器对象。它生成一个具有两个元素的类数组的对象,第一个元素是将用作属性键的值,第二个元素是与该属性键关联的值。
Object.fromEntries()
执行与 Object.entries
互逆的操作。
// Map 转化为 Object
const map = new Map([ ['foo', 'bar'], ['baz', 42] ]);
const obj = Object.fromEntries(map);
console.log(obj); // { foo: "bar", baz: 42 }
// Array 转化为 Object
const arr = [ ['0', 'a'], ['1', 'b'], ['2', 'c'] ];
const obj = Object.fromEntries(arr);
console.log(obj); // { 0: "a", 1: "b", 2: "c" }
Object.create
note
Object.create()
方法用于创建一个新对象,使用现有的对象来作为新创建对象的原型(prototype)。
Object.getPrototypeOf
note
Object.getPrototypeOf()
方法返回指定对象的原型(内部[[Prototype]]
属性的值)。
Object.is
用于判断两个值是否相同。
// Case 1: Evaluation result is the same as using ===
Object.is(25, 25); // true
Object.is("foo", "foo"); // true
Object.is("foo", "bar"); // false
Object.is(null, null); // true
Object.is(undefined, undefined); // true
Object.is(window, window); // true
Object.is([], []); // false
const foo = { a: 1 };
const bar = { a: 1 };
const sameFoo = foo;
Object.is(foo, foo); // true
Object.is(foo, bar); // false
Object.is(foo, sameFoo); // true
// Case 2: Signed zero
Object.is(0, -0); // false
Object.is(+0, -0); // false
Object.is(-0, -0); // true
// Case 3: NaN
Object.is(NaN, 0 / 0); // true
Object.is(NaN, Number.NaN); // true
Object.entries
let a = {1: 'a'};
Object.entries(a) // [["1","a"]]
Object.values
let a = {1: 'a'};
Object.values(a) // ["a"]
Object.freeze
可以使一个对象被冻结,冻结对象可以防止扩展,并使现有的属性不可写入和不可配置。
被冻结的对象不能再被更改:不能添加新的属性,不能移除现有的属性,不能更改它们的可枚举性、可配置性、可写性或值,对象的原型也不能被重新指定。
Object.freeze(obj)
返回与传入的对象相同的对象。
const obj = {
prop: 42,
};
Object.freeze(obj);
obj.prop = 33;
// Throws an error in strict mode
console.log(obj.prop);
// Expected output: 42
String
replaceAll、replace
这俩方法并不改变调用它的字符串本身,而是返回一个新的字符串。
const str = ' A B C D ';
console.log(str.replaceAll(' ', '+')); // +A+++B+++C++++D+
console.log(str.replace(/ /g, '+')); // +A+++B+++C++++D+
数组
Array.prototype.shift()
- 从数组中删除第一个元素,并返回该元素的值。此方法更改数组的长度。
- shift 方法会读取
this
的 length 属性,如果长度为 0,length 再次设置为 0(而之前可能为负值或 undefined)。否则,返回 0 处的属性,其余属性向左移动 1。length 属性递减 1。
Array.prototype.sort()
- 对数组的元素进行排序,此方法改变原数组。如果想要不改变原数组的排序方法,可以使用
Array.prototype.toSorted()
。
循环
Array.prototype.forEach()
info
除了抛出异常以外,没有办法中止或跳出 forEach() 循环。若你需要提前终止循环,你可以使用:
- 一个简单的 for 循环
- for...of / for...in 循环
- Array.prototype.every()
- Array.prototype.some()
- Array.prototype.find()
- Array.prototype.findIndex()
forEach中的return:退出当前函数,但迭代继续。
for...of
- 对于for...of的循环,可以由 break, throw 或 return 终止。
- for...of 语句遍历可迭代对象定义要迭代的数据。
若一个对象拥有迭代行为,那么这个对象便是一个可迭代对象。为了实现可迭代,一个对象必须实现 @@iterator 方法,这意味着这个对象(或其原型链中的任意一个对象)必须具有一个带 Symbol.iterator 键(key)的属性。
// 自定义可迭代对象
var myIterable = {
*[Symbol.iterator]() {
yield 1;
yield 2;
yield 3;
}
}
for (let value of myIterable) {
console.log(value);
}
console.log([...myIterable])
for...in
for...in 语句以任意顺序迭代一个对象的除Symbol以外的可枚举属性,包括继承的可枚举属性。
可枚举属性是指那些内部“可枚举”标志设置为 true 的属性,对于通过直接的赋值和属性初始化的属性,该标识值默认为 true,对于通过
Object.defineProperty
等定义的属性,该标识值默认为 false。for...in不应该用于迭代一个关注索引顺序的 Array。
for...in是为遍历对象属性而构建的,不建议与数组一起使用,数组可以用Array.prototype.forEach()和for...of
for...of 和 for...in的区别
Object.prototype.objCustom = function() {};
Array.prototype.arrCustom = function() {};
let iterable = [3, 5, 7];
iterable.foo = 'hello';
for (let i in iterable) {
console.log('forin::', i); // 0 1 2 foo arrCustom objCustom
}
for (let i in iterable) {
if (iterable.hasOwnProperty(i)) {
console.log('forin-iterable has property::', i); // 0 1 2 foo
}
}
for (let i of iterable) {
console.log('forof::', i); // 3 5 7
}
Reflect
Reflect
是 JavaScript 中的一个内置对象,提供了一些用于操作对象的静态方法。这些方法与 Object
对象的方法类似,但 Reflect
的方法更为一致和可靠,特别是在处理代理(Proxy
)时。
常用的 Reflect
方法
Reflect.apply(target, thisArgument, argumentsList)
调用一个目标函数,并指定
this
值和参数列表。function sum(a, b) {
return a + b;
}
console.log(Reflect.apply(sum, null, [1, 2])); // 输出: 3Reflect.construct(target, argumentsList[, newTarget])
类似于
new
操作符,但以函数形式调用。function Person(name) {
this.name = name;
}
const person = Reflect.construct(Person, ['Alice']);
console.log(person.name); // 输出: AliceReflect.defineProperty(target, propertyKey, attributes)
与
Object.defineProperty
类似,用于定义或修改对象的属性。const obj = {};
Reflect.defineProperty(obj, 'name', { value: 'Alice' });
console.log(obj.name); // 输出: AliceReflect.deleteProperty(target, propertyKey)
删除对象的属性,类似于
delete
操作符。const obj = { name: 'Alice' };
Reflect.deleteProperty(obj, 'name');
console.log(obj.name); // 输出: undefinedReflect.get(target, propertyKey[, receiver])
获取对象的属性值。
const obj = { name: 'Alice' };
console.log(Reflect.get(obj, 'name')); // 输出: AliceReflect.set(target, propertyKey, value[, receiver])
设置对象的属性值。
const obj = {};
Reflect.set(obj, 'name', 'Alice');
console.log(obj.name); // 输出: AliceReflect.has(target, propertyKey)
检查对象是否具有某个属性,类似于
in
操作符。const obj = { name: 'Alice' };
console.log(Reflect.has(obj, 'name')); // 输出: trueReflect.ownKeys(target)
返回一个包含对象自身属性键的数组,包括符号属性。
const obj = { name: 'Alice', [Symbol('id')]: 123 };
console.log(Reflect.ownKeys(obj)); // 输出: ['name', Symbol(id)]
Reflect
对象的方法提供了一种更为一致和功能强大的方式来操作 JavaScript 对象,特别是在使用代理(Proxy
)时非常有用。
Reflect
和 Object
Reflect
和 Object
都是 JavaScript 中的内置对象,它们提供了一些用于操作对象的方法。虽然它们有一些相似之处,但也有一些关键的区别。
Reflect
提供了一组与Object
方法类似但更为一致和可靠的方法,特别是在处理代理(Proxy)时非常有用。Reflect
方法通常返回布尔值,表示操作是否成功,而Object
方法在失败时会抛出异常。Reflect
的方法名与Proxy
的处理程序方法名相对应,使得在代理中调用默认行为变得更加简单和一致。
通过结合使用 Reflect
和 Object
,你可以更灵活地操作 JavaScript 对象,并在需要时调用默认行为。
相似之处
许多 Reflect
方法与 Object
方法功能相似,甚至有些方法的名称和参数完全相同。例如:
Reflect.defineProperty
与Object.defineProperty
Reflect.getOwnPropertyDescriptor
与Object.getOwnPropertyDescriptor
Reflect.getPrototypeOf
与Object.getPrototypeOf
Reflect.setPrototypeOf
与Object.setPrototypeOf
不同之处
返回值:
Reflect
方法通常返回一个布尔值,表示操作是否成功,而Object
方法在失败时会抛出异常。- 例如,
Reflect.defineProperty
返回true
或false
,而Object.defineProperty
在失败时会抛出异常。
一致性:
Reflect
提供了一组更为一致的方法,这些方法的命名和参数设计都遵循统一的规则。Reflect
的方法名与Proxy
的处理程序方法名相对应,使得在代理中调用默认行为变得更加简单和一致。
Reflect.defineProperty
vs Object.defineProperty
const obj = {};
// 使用 Object.defineProperty
try {
Object.defineProperty(obj, 'name', { value: 'Alice' });
console.log(obj.name); // 输出: Alice
} catch (e) {
console.error(e);
}
// 使用 Reflect.defineProperty
const success = Reflect.defineProperty(obj, 'name', { value: 'Alice' });
if (success) {
console.log(obj.name); // 输出: Alice
} else {
console.error('Failed to define property');
}
Reflect.getOwnPropertyDescriptor
vs Object.getOwnPropertyDescriptor
const obj = { name: 'Alice' };
// 使用 Object.getOwnPropertyDescriptor
const descriptor1 = Object.getOwnPropertyDescriptor(obj, 'name');
console.log(descriptor1); // 输出: { value: 'Alice', writable: true, enumerable: true, configurable: true }
// 使用 Reflect.getOwnPropertyDescriptor
const descriptor2 = Reflect.getOwnPropertyDescriptor(obj, 'name');
console.log(descriptor2); // 输出: { value: 'Alice', writable: true, enumerable: true, configurable: true }
Reflect.getPrototypeOf
vs Object.getPrototypeOf
const obj = {};
// 使用 Object.getPrototypeOf
const proto1 = Object.getPrototypeOf(obj);
console.log(proto1); // 输出: {}
// 使用 Reflect.getPrototypeOf
const proto2 = Reflect.getPrototypeOf(obj);
console.log(proto2); // 输出: {}
Proxy
Proxy
是 JavaScript 中的一个构造函数,用于创建一个代理对象,可以拦截和自定义基本操作(例如属性查找、赋值、枚举、函数调用等)。通过使用 Proxy
,你可以定义自定义行为来处理这些操作。
以下是一些关于 Proxy
的基本概念和示例:
基本语法
const proxy = new Proxy(target, handler);
target
:要包装的目标对象(可以是任何类型的对象,包括数组、函数等)。handler
:一个对象,其属性是当执行一个操作时定义代理行为的函数。
示例
- 基本示例
const target = {
message: "Hello, world!"
};
const handler = {
get: function(target, property) {
if (property === 'message') {
return target[property].toUpperCase();
}
return target[property];
}
};
const proxy = new Proxy(target, handler);
console.log(proxy.message); // 输出: HELLO, WORLD!
- 拦截属性设置
const target = {
name: "Alice"
};
const handler = {
set: function(target, property, value) {
if (property === 'name' && typeof value === 'string') {
target[property] = value.toUpperCase();
return true;
}
return false;
}
};
const proxy = new Proxy(target, handler);
proxy.name = "Bob";
console.log(proxy.name); // 输出: BOB
- 拦截函数调用
const target = function(name) {
return `Hello, ${name}!`;
};
const handler = {
apply: function(target, thisArg, argumentsList) {
return target(argumentsList[0]).toUpperCase();
}
};
const proxy = new Proxy(target, handler);
console.log(proxy("Alice")); // 输出: HELLO, ALICE!
- 拦截属性删除
const target = {
name: "Alice"
};
const handler = {
deleteProperty: function(target, property) {
if (property === 'name') {
console.log(`Deleting property ${property}`);
delete target[property];
return true;
}
return false;
}
};
const proxy = new Proxy(target, handler);
delete proxy.name; // 输出: Deleting property name
console.log(proxy.name); // 输出: undefined
常用的 Proxy
处理程序方法
get(target, property, receiver)
:拦截对象属性的读取操作。set(target, property, value, receiver)
:拦截对象属性的设置操作。has(target, property)
:拦截in
操作符。deleteProperty(target, property)
:拦截delete
操作符。apply(target, thisArg, argumentsList)
:拦截函数调用。construct(target, argumentsList, newTarget)
:拦截new
操作符。
Proxy
对象提供了强大的功能,可以用来创建灵活和动态的对象行为,适用于各种高级编程场景。
Proxy
和 Reflect
结合使用
Proxy
和 Reflect
可以结合使用,以便在代理对象中更方便地调用默认行为。Reflect
提供了一组与 Proxy
处理程序方法对应的静态方法,这使得在代理中调用默认行为变得更加简单和一致。
以下是一些示例,展示了如何结合使用 Proxy
和 Reflect
:
示例 1: 拦截属性读取
const target = {
message: "Hello, world!"
};
const handler = {
get: function(target, property, receiver) {
// 自定义行为:将 message 属性转换为大写
if (property === 'message') {
return Reflect.get(target, property, receiver).toUpperCase();
}
// 默认行为
return Reflect.get(target, property, receiver);
}
};
const proxy = new Proxy(target, handler);
console.log(proxy.message); // 输出: HELLO, WORLD!
console.log(proxy.nonExistent); // 输出: undefined
示例 2: 拦截属性设置
const target = {
name: "Alice"
};
const handler = {
set: function(target, property, value, receiver) {
// 自定义行为:将 name 属性的值转换为大写
if (property === 'name' && typeof value === 'string') {
return Reflect.set(target, property, value.toUpperCase(), receiver);
}
// 默认行为
return Reflect.set(target, property, value, receiver);
}
};
const proxy = new Proxy(target, handler);
proxy.name = "Bob";
console.log(proxy.name); // 输出: BOB
示例 3: 拦截函数调用
const target = function(name) {
return `Hello, ${name}!`;
};
const handler = {
apply: function(target, thisArg, argumentsList) {
// 自定义行为:将返回值转换为大写
return Reflect.apply(target, thisArg, argumentsList).toUpperCase();
}
};
const proxy = new Proxy(target, handler);
console.log(proxy("Alice")); // 输出: HELLO, ALICE!
示例 4: 拦截属性删除
const target = {
name: "Alice"
};
const handler = {
deleteProperty: function(target, property) {
// 自定义行为:记录删除操作
if (property === 'name') {
console.log(`Deleting property ${property}`);
return Reflect.deleteProperty(target, property);
}
// 默认行为
return Reflect.deleteProperty(target, property);
}
};
const proxy = new Proxy(target, handler);
delete proxy.name; // 输出: Deleting property name
console.log(proxy.name); // 输出: undefined
示例 5: 在Vue项目中使用
<el-button type="primary" @click="proxySubmit">提交</el-button>
import { riskSubmitHandler } from './handlers.js';
export default {
data() {
return {
riskNoticeVisible: false,
riskNoticeMessage: '',
submitSuccess: null,
}
},
methods: {
proxySubmit() {
const proxy = new Proxy(this.submit, riskSubmitHandler);
// 业务逻辑...
const promise = proxy(param1, param2);
promise.then(result => {
if (Object.prototype.toString.call(result) == '[object Object]') {
const { canSubmit, dialogMessage } = result;
this.riskNoticeMessage = dialogMessage;
this.submitSuccess = canSubmit;
this.riskNoticeVisible = !canSubmit;
} else {
this.riskNoticeMessage = '';
this.submitSuccess = null;
this.riskNoticeVisible = false;
}
})
},
submit() {
// ...
},
}
}
export const riskSubmitHandler = {
apply: async function(target, thisArg, args) {
const param1 = args[0];
const param2 = args[1];
if (param1 && param2) {
try {
const result = await riskVerifyApi({
param1,
param2,
});
const { riskState, noticeDesc } = result;
switch (riskState) {
case 0:
return Reflect.apply(target, thisArg, args);
case 1:
// 卡流程
return {
canSubmit: false,
dialogMessage: noticeDesc,
};
case 2:
Reflect.apply(target, thisArg, args);
return {
canSubmit: true,
dialogMessage: noticeDesc,
};
default:
return Reflect.apply(target, thisArg, args);
}
} catch (error) {
// 接口异常不卡流程
return Reflect.apply(target, thisArg, args);
}
} else {
return Reflect.apply(target, thisArg, args);
}
}
};
Proxy
和 Reflect
结合使用的好处
结合使用 Proxy
和 Reflect
可以带来以下好处:
- 简化默认行为调用:使用
Reflect
可以更方便地调用默认行为。 - 提高代码一致性:
Reflect
方法与Proxy
处理程序方法相对应,使代码更为一致和易读。 - 提供更好的错误处理:
Reflect
方法返回布尔值,便于处理错误情况。 - 更灵活的代理行为:可以在代理中实现复杂的逻辑,同时保留对默认行为的访问。
通过这些好处,你可以更高效地创建和管理代理对象,提高代码的可维护性和可靠性。
简化默认行为调用
使用
Reflect
可以简化在Proxy
处理程序中调用默认行为的过程。Reflect
提供了一组与Proxy
处理程序方法对应的静态方法,使得代码更为简洁和一致。const target = {
message: "Hello, world!"
};
const handler = {
get: function(target, property, receiver) {
// 自定义行为:将 message 属性转换为大写
if (property === 'message') {
return Reflect.get(target, property, receiver).toUpperCase();
}
// 默认行为
return Reflect.get(target, property, receiver);
}
};
const proxy = new Proxy(target, handler);
console.log(proxy.message); // 输出: HELLO, WORLD!
console.log(proxy.nonExistent); // 输出: undefined提高代码一致性
Reflect
方法的命名和参数设计与Proxy
处理程序方法相对应,使得代码更为一致和易读。这种一致性有助于减少错误并提高代码的可维护性。const target = {
name: "Alice"
};
const handler = {
set: function(target, property, value, receiver) {
// 自定义行为:将 name 属性的值转换为大写
if (property === 'name' && typeof value === 'string') {
return Reflect.set(target, property, value.toUpperCase(), receiver);
}
// 默认行为
return Reflect.set(target, property, value, receiver);
}
};
const proxy = new Proxy(target, handler);
proxy.name = "Bob";
console.log(proxy.name); // 输出: BOB提供更好的错误处理
Reflect
方法通常返回布尔值,表示操作是否成功,而不是抛出异常。这使得在Proxy
处理程序中更容易处理错误情况。const target = {};
const handler = {
defineProperty: function(target, property, descriptor) {
// 自定义行为:记录属性定义操作
console.log(`Defining property ${property}`);
return Reflect.defineProperty(target, property, descriptor);
}
};
const proxy = new Proxy(target, handler);
const success = Reflect.defineProperty(proxy, 'name', { value: 'Alice' });
if (success) {
console.log(proxy.name); // 输出: Alice
} else {
console.error('Failed to define property');
}更灵活的代理行为
通过结合使用
Proxy
和Reflect
,你可以更灵活地定义和管理代理对象的行为。例如,你可以在代理中实现复杂的逻辑,同时保留对默认行为的访问。const target = {
name: "Alice"
};
const handler = {
deleteProperty: function(target, property) {
// 自定义行为:记录删除操作
if (property === 'name') {
console.log(`Deleting property ${property}`);
return Reflect.deleteProperty(target, property);
}
// 默认行为
return Reflect.deleteProperty(target, property);
}
};
const proxy = new Proxy(target, handler);
delete proxy.name; // 输出: Deleting property name
console.log(proxy.name); // 输出: undefined
Intl
Intl 对象是 ECMAScript 国际化 API 的一个命名空间,它提供了精确的字符串对比、数字格式化,和日期时间格式化。
Web API(浏览器环境提供的宿主对象)
Crypto
Crypto 接口提供了基本的加密功能,可用于当前的上下文中。
在浏览器控制台可以如下使用:
但是在js中不能使用
randomUUID()
及self
对象,可以使用getRandomValues
:
const array = new Uint32Array(1);
window.crypto.getRandomValues(array);
console.log(JSON.stringify(array));
Window
window.prompt
显示一个对话框,对话框中包含一条文字信息,用来提示用户输入文字。
result = window.prompt(text, value);
// result 用来存储用户输入文字的字符串,或者是 null。 // text 用来提示用户输入文字的字符串,如果没有任何提示内容,该参数可以省略不写。 // value 文本输入框中的默认值,该参数也可以省略不写。不过在 Internet Explorer 7 和 8 中,省略该参数会导致输入框中显示默认值"undefined"。
#### `window.getComputedStyle`
> 获取指定元素的的所有 CSS 属性的值
```js
const currentCell = document.getElementById(refValue);
const parentWidth = currentCell.parentNode.offsetWidth;
const contentWidth = currentCell.offsetWidth;
const parentStyle = document.defaultView.getComputedStyle(currentCell.parentNode, '');
const paddingValue = parseInt(parentStyle.paddingLeft.replace('px', '')) + parseInt(parentStyle.paddingRight.replace('px', ''));
window.requestAnimationFrame
window.requestAnimationFrame()
是一个由浏览器提供的 JavaScript 方法,用于告诉浏览器你希望执行一个动画,并要求浏览器在下次重绘之前调用指定的回调函数来更新动画。这个方法接受一个回调函数作为参数,该回调函数将在浏览器准备好重绘画面时被调用。
使用 requestAnimationFrame
有几个好处:
- 高效性能:浏览器可以选择最佳的时间来执行动画,从而保证动画的流畅性。
- 节省资源:当页面不在浏览器的可视区域时,
requestAnimationFrame
会暂停调用回调函数,从而节省处理器资源和电池寿命。 - 更好的帧控制:它允许浏览器在每一帧中只执行一次屏幕重绘,避免不必要的布局和重绘,减少页面抖动。
requestAnimationFrame
返回一个长整型数字,这个数字是请求 ID,你可以将它传递给 window.cancelAnimationFrame()
来取消请求。这在动画不再需要继续时非常有用,例如,当用户导航到不同的页面或动画已经完成时。
window.performance
window.performance
是浏览器提供的一个全局对象,它提供了获取当前页面相关性能信息的功能。这个对象是 Web 性能 API 的一部分,它允许开发者精确地测量和监控网页性能。
window.performance
对象包含了一系列子对象和方法,其中一些主要的包括:
performance.now()
:返回一个高精度的时间戳,单位为毫秒,相对于performance.timing.navigationStart
的时间。这个方法可以用于精确的性能测量。performance.timing
:一个包含了与当前页面相关的一系列性能指标的对象,例如页面加载、解析等各个阶段的时间点。这个属性在新的性能 API 中已被废弃,被PerformanceNavigationTiming
接口取代。performance.getEntries()
:返回一个PerformanceEntry
对象的列表,这些对象包含了页面上各种资源(如脚本、样式表、图片等)的加载时间信息。performance.mark()
:用于创建一个具有指定名称的时间戳(标记),这些标记可以用于测量代码执行的时间。performance.measure()
:用于创建一个PerformanceMeasure
对象,它表示两个标记之间的时间间隔。performance.navigation
:提供了有关如何导航到当前页面的信息。例如,用户是通过点击链接、表单提交还是浏览器历史记录等方式来到当前页面的。performance.clearMarks()
和performance.clearMeasures()
:用于清除由performance.mark()
和performance.measure()
创建的标记和测量。performance.getEntriesByType()
和performance.getEntriesByName()
:允许按类型或名称检索特定的性能条目。
window.performance
对象是监控和优化网页性能的重要工具,它可以帮助开发者了解页面加载和执行的具体情况,从而找出性能瓶颈并进行优化。随着 Web 性能 API 的发展,一些新的接口和功能(如 PerformanceObserver
)也被引入,以提供更丰富的性能数据和更灵活的监控方式。
Node
各种类型的 DOM API 对象会从这个接口继承
Node.appendChild()
Node.appendChild()
方法将一个节点附加到指定父节点的子节点列表的末尾处。如果将被插入的节点已经存在于当前文档的文档树中,那么 appendChild()
只会将它从原先的位置移动到新的位置(不需要事先移除要移动的节点)。
XMLHttpRequest
XMLHttpRequest (XHR) 对象用于与服务器交互,这使网页可以只更新页面的一部分,而不会中断用户正在做的事情。
function upload(options: any) {
const xhr = new XMLHttpRequest()
xhr.timeout = options.timeout
if (xhr.upload) {
xhr.upload.addEventListener(
'progress',
(e: ProgressEvent<XMLHttpRequestEventTarget>) => {
options.onProgress?.(e, options)
},
false
)
xhr.onreadystatechange = () => {
if (xhr.readyState === 4) {
if (xhr.status === options.xhrState) {
options.onSuccess?.(xhr.responseText, options)
} else {
options.onFailure?.(xhr.responseText, options)
}
}
}
xhr.withCredentials = options.withCredentials
xhr.open(options.method, options.url, true)
// headers
for (const [key, value] of Object.entries(options.headers)) {
xhr.setRequestHeader(key, value as string)
}
options.onStart?.(options)
if (options.beforeXhrUpload) {
options.beforeXhrUpload(xhr, options)
} else {
xhr.send(options.formData)
}
} else {
console.warn('浏览器不支持 XMLHttpRequest')
}
}
Fetch API
fetch()
FormData
FormData 接口提供了一种表示表单数据的键值对 key/value 的构造方式,可以使用 fetch() 或 XMLHttpRequest.send() 方法发送这些值。如果编码类型设置为“multipart/form-data”,它使用的格式与表单使用的格式相同。
URL API
URLSearchParams
const paramsString1 = 'http://example.com/search?query=%40';
const searchParams1 = new URLSearchParams(paramsString1);
console.log(searchParams1.has('query')); // false
console.log(searchParams1.has('http://example.com/search?query')); // true
console.log(searchParams1.get('query')); // null
console.log(searchParams1.get('http://example.com/search?query')); // "@" (equivalent to decodeURIComponent('%40'))
const paramsString2 = '?query=value';
const searchParams2 = new URLSearchParams(paramsString2);
console.log(searchParams2.has('query')); // true
const url = new URL('http://example.com/search?query=%40');
const searchParams3 = new URLSearchParams(url.search);
console.log(searchParams3.has('query')); // true
append(name, value)
delete(name)
Document
querySelectorAll
获取整个页面中class前缀都为"operation"的元素:
document.querySelectorAll('[class^="operation"]')
base64
base64解密
- 浏览器中
const decodedData = window.atob(encodedData);
- Service Workers和Web Workers中
const decodedData = self.atob(encodedData);
base64加密
- 浏览器中
const encodedData = window.btoa(stringToEncode);
- Service Workers和Web Workers中
const encodedData = self.btoa(stringToEncode);
HTMLElement
dragstart
当用户开始拖动一个元素或者一个选择文本的时候 dragstart 事件就会触发。
dragend
dragend 事件在拖放操作结束时触发(通过释放鼠标按钮或单击 escape 键)。该事件无法取消。
dragenter
当拖动的元素或被选择的文本进入有效的放置目标时, dragenter 事件被触发。
dragleave
dragleave 事件在拖动的元素或选中的文本离开一个有效的放置目标时被触发。此事件不可取消。
dragover
当元素或者选择的文本被拖拽到一个有效的放置目标上时,触发 dragover 事件(每几百毫秒触发一次)。这个事件在可被放置元素的节点上触发。
drag
drag 事件在用户拖动元素或选择的文本时,每隔几百毫秒就会被触发一次。
drop
drop 事件在元素或选中的文本被放置在有效的放置目标上时被触发。
- 在 dragstart 事件处理器中,获得对用户拖动的元素的引用。
- 在目标容器的 dragover 事件处理器中,调用 event.preventDefault(),以使得该元素能够接收 drop 事件。
- 在放置区域的 drop 事件处理器中,将可拖动元素从原先的容器移动到该放置区域。