其他
微任务
- queueMicrotask
js
const callback = () => console.log(1);
queueMicrotask(callback);
const callback = () => console.log(1);
queueMicrotask(callback);
- Promise.then
js
const callback = () => console.log(1);
const pm = Promise.resolve();
pm.then(callback);
const callback = () => console.log(1);
const pm = Promise.resolve();
pm.then(callback);
- MutationObserver
js
let observer;
let comment = document.createComment('MutationObserver');
let callback = () => {
console.log(1);
comment.remove();
observer.disconnect();
};
observer = new MutationObserver(callback);
observer.observe(document.head, { childList: true });
document.head.append(comment);
let observer;
let comment = document.createComment('MutationObserver');
let callback = () => {
console.log(1);
comment.remove();
observer.disconnect();
};
observer = new MutationObserver(callback);
observer.observe(document.head, { childList: true });
document.head.append(comment);
HTML 模版引擎
js
let template = '我是{{name}},年龄{{age}},性别{{sex}}';
let data = { name: '姓名', age: 18 };
console.log(render(template, data)); // 我是姓名,年龄18,性别 undefined
function render(template = '', data = {}) {
const reg = /\{\{(\w+)\}\}/;
const [match, group] = template.match(reg) || [];
if (match) {
let new_template = template.replace(reg, String(data[group]));
return render(new_template, data);
}
return template;
}
let template = '我是{{name}},年龄{{age}},性别{{sex}}';
let data = { name: '姓名', age: 18 };
console.log(render(template, data)); // 我是姓名,年龄18,性别 undefined
function render(template = '', data = {}) {
const reg = /\{\{(\w+)\}\}/;
const [match, group] = template.match(reg) || [];
if (match) {
let new_template = template.replace(reg, String(data[group]));
return render(new_template, data);
}
return template;
}
数字转字符串
js
// 样例输入:1234567890
// 样例输出:1,234,567,890
function transform(num, n = 1) {
// 这是最简单的写法 num.toLocaleString();
let num1 = num % 10;
let num2 = (num - num1) / 10;
if (num < 10) return String(num1);
let joinNum1 = n % 3 === 0 ? ',' + num1 : num1;
return transform(num2, n + 1) + joinNum1;
}
// 样例输入:1234567890
// 样例输出:1,234,567,890
function transform(num, n = 1) {
// 这是最简单的写法 num.toLocaleString();
let num1 = num % 10;
let num2 = (num - num1) / 10;
if (num < 10) return String(num1);
let joinNum1 = n % 3 === 0 ? ',' + num1 : num1;
return transform(num2, n + 1) + joinNum1;
}
非递减数组
非递减数组就是相邻的两项递增或者相同的数组,例如: [1, 1, 2, 2, 5]
非递减数组打印不重复值
- 一个非递减数组,打印非递减数组项,当项重复时只打印第一项
js
var uniqueLog = function (nums = []) {
// 改造成非递减数组排序
nums.sort((a, b) => a - b);
// 遍历非递减数组
for (let i = 0; i < nums.length; i++) {
// 跳过重复项
for (; i > 0 && nums[i] === nums[i - 1]; i++);
// 打印唯一值
console.log(nums[i]);
}
};
// let list = [1, 3, 2, 3, 1, 3, 2, 3, 1]
// console.log(uniqueLog(list));
// > 1 2 3
var uniqueLog = function (nums = []) {
// 改造成非递减数组排序
nums.sort((a, b) => a - b);
// 遍历非递减数组
for (let i = 0; i < nums.length; i++) {
// 跳过重复项
for (; i > 0 && nums[i] === nums[i - 1]; i++);
// 打印唯一值
console.log(nums[i]);
}
};
// let list = [1, 3, 2, 3, 1, 3, 2, 3, 1]
// console.log(uniqueLog(list));
// > 1 2 3
in 与 forin
如果指定的属性
在指定的对象或其原型链
中,则 in 运算符返回 true。
js
const car = { make: 'Honda', model: 'Accord', year: 1998 };
console.log('make' in car); // true
const car = { make: 'Honda', model: 'Accord', year: 1998 };
console.log('make' in car); // true
Object.defineProperty
js
Object.defineProperty(obj, 'attr', {
configurable: true, // 默认 true;表示能否使用 delete 删除属性从而重新定义属性。
enumerable: true, // 默认 true;表示能否通过 for-in 循环返回属性。
writable: true, // 默认 true;表示能否修改属性值。
value: undefined, // 默认 undefined;表示属性的值。
set: undefined, // 默认 undefined;表示写入属性时调用函数。
get: undefined // 默认 undefined;表示读取属性时调用函数。
});
Object.defineProperty(obj, 'attr', {
configurable: true, // 默认 true;表示能否使用 delete 删除属性从而重新定义属性。
enumerable: true, // 默认 true;表示能否通过 for-in 循环返回属性。
writable: true, // 默认 true;表示能否修改属性值。
value: undefined, // 默认 undefined;表示属性的值。
set: undefined, // 默认 undefined;表示写入属性时调用函数。
get: undefined // 默认 undefined;表示读取属性时调用函数。
});
structuredClone
valueOf
JavaScript 调用 valueOf 方法来将对象转换成基本类型值
。你很少需要自己调用 valueOf 方法;当遇到需要基本类型值的对象时,JavaScript 会自动的调用该方法。
强制数字类型转换和强制基本类型转换优先会调用该方法,而强制字符串转换会优先调用 toString(),并且 toString() 很可能返回字符串值(甚至对于 Object.prototype.toString() 基本实现也是如此),因此在这种情况下不会调用 valueOf()。
js
var obj = {
valueOf: () => 'valueOf'
};
console.log(+obj); // NaN
console.log('' + obj); // valueOf
function fn() {
fn.valueOf = () => 42;
return fn;
}
console.log(fn()); // ƒ fn(){...}
console.log(+fn()); // 42
console.log('' + fn()); // "42"
+new Date(); // 当前时间戳;与 new Date().getTime() 相同
+{}; // NaN(toString() 返回 "[object Object]")
+[]; // 0(toString() 返回一个空的字符串列表)
+[1]; // 1(toString() 返回 "1")
+[1, 2]; // NaN(toString() 返回 "1,2")
+new Set([1]); // NaN(toString() 返回 "[object Set]")
+{ valueOf: () => 42 }; // 42
// chain 链式函数
function chain(x) {
const fn = (y) => chain(x * y); // 阶乘
fn.valueOf = () => x; // 类型转换
return fn;
}
// 使用 “+” 类型转换被动调用 valueOf
console.log(+chain(1)(2)(3)(4)); // 42
// 主动调用 valueOf
console.log(chain(1)(2)(3)(4).valueOf()); // 42
var obj = {
valueOf: () => 'valueOf'
};
console.log(+obj); // NaN
console.log('' + obj); // valueOf
function fn() {
fn.valueOf = () => 42;
return fn;
}
console.log(fn()); // ƒ fn(){...}
console.log(+fn()); // 42
console.log('' + fn()); // "42"
+new Date(); // 当前时间戳;与 new Date().getTime() 相同
+{}; // NaN(toString() 返回 "[object Object]")
+[]; // 0(toString() 返回一个空的字符串列表)
+[1]; // 1(toString() 返回 "1")
+[1, 2]; // NaN(toString() 返回 "1,2")
+new Set([1]); // NaN(toString() 返回 "[object Set]")
+{ valueOf: () => 42 }; // 42
// chain 链式函数
function chain(x) {
const fn = (y) => chain(x * y); // 阶乘
fn.valueOf = () => x; // 类型转换
return fn;
}
// 使用 “+” 类型转换被动调用 valueOf
console.log(+chain(1)(2)(3)(4)); // 42
// 主动调用 valueOf
console.log(chain(1)(2)(3)(4).valueOf()); // 42
cookie
http
Set-Cookie: <cookie-name>=<cookie-value>
Set-Cookie: <cookie-name>=<cookie-value>; Expires=<date>
Set-Cookie: <cookie-name>=<cookie-value>; Max-Age=<number>
Set-Cookie: <cookie-name>=<cookie-value>; Domain=<domain-value>
Set-Cookie: <cookie-name>=<cookie-value>; Path=<path-value>
Set-Cookie: <cookie-name>=<cookie-value>; Secure
Set-Cookie: <cookie-name>=<cookie-value>; HttpOnly
Set-Cookie: <cookie-name>=<cookie-value>; SameSite=Strict
Set-Cookie: <cookie-name>=<cookie-value>; SameSite=Lax
Set-Cookie: <cookie-name>=<cookie-value>; SameSite=None; Secure
// Multiple attributes are also possible, for example:
Set-Cookie: <cookie-name>=<cookie-value>; Domain=<domain-value>; Secure; HttpOnly
Set-Cookie: <cookie-name>=<cookie-value>
Set-Cookie: <cookie-name>=<cookie-value>; Expires=<date>
Set-Cookie: <cookie-name>=<cookie-value>; Max-Age=<number>
Set-Cookie: <cookie-name>=<cookie-value>; Domain=<domain-value>
Set-Cookie: <cookie-name>=<cookie-value>; Path=<path-value>
Set-Cookie: <cookie-name>=<cookie-value>; Secure
Set-Cookie: <cookie-name>=<cookie-value>; HttpOnly
Set-Cookie: <cookie-name>=<cookie-value>; SameSite=Strict
Set-Cookie: <cookie-name>=<cookie-value>; SameSite=Lax
Set-Cookie: <cookie-name>=<cookie-value>; SameSite=None; Secure
// Multiple attributes are also possible, for example:
Set-Cookie: <cookie-name>=<cookie-value>; Domain=<domain-value>; Secure; HttpOnly