手写算法: 最大子数组和
思路
按照加法的顺序来算,从数组的最后一位开始 ➕1,判断加完的数字是否等于 10,就是需要进位。
可以分三种情况:
若无进位,那么前面也一定不会有进位的地方,直接 return 出去即可。
若有进位,则当前位应该为 0,前一位 ➕1,直到加到不为 0 为止,如 499 -> 500。
若有进位且一直需要进位,导致多处一位,那么就要单独处理,新建一个长度为 len+1 的新数组,全部填充 0, 首位改成 1 即可。
function plusOne(nums) {
const len = nums.length;
for (let i = len - 1; i >= 0; i--) {
nums[i]++;
// 计算加一后,是否需要进位,取模为0的话,那么就是要进位
nums[i] %= 10;
// 不需要进位,则直接return即可
if (nums[i] !== 0) {
return nums;
}
}
// 判断特殊情况,全部都为9,结果超出当前数组长度,需要扩充数组
nums = new Array(len + 1).fill(0);
nums[0] = 1;
return nums;
}
手写题: 手写 Selection Sort
用冒泡排序实现
/**
* @param {number[]} arr
*/
function selectionSort(arr) {
// your code here
const len = arr.length;
for (let i = 0; i < len - 1; i++) {
for (let j = 0; j < len - i - 1; j++) {
if (arr[j + 1] < arr[j]) {
let temp = arr[j + 1];
arr[j + 1] = arr[j];
arr[j] = temp;
}
}
}
return arr;
}
JS 简答题
RegExp.prototype.test
console.log(/^4\d\d$/.test('404'));
console.log(/^4\d\d$/.test(404));
console.log(/^4\d\d$/.test(['404']));
console.log(/^4\d\d$/.test([404]));
解析
分析正则
/^4\d\d$/, 表示以数字 4 开头,后跟数字,并以数字结尾RegExp.test(), 入参为
string, 用来与正则表达式匹配的字符串。 如果传入的不是字符串,则先转成字符串再进行匹配。
console.log(/^4\d\d$/.test('404')); // true
console.log(/^4\d\d$/.test(404)); // true -> 404..toString()
console.log(/^4\d\d$/.test(['404'])); // true -> ['404'].toString()
console.log(/^4\d\d$/.test([404])); // true -> [404].toString()
array keys
console.log(Reflect.ownKeys([]));
console.log(Reflect.ownKeys([,]));
console.log(Reflect.ownKeys([1, , 2]));
console.log(Reflect.ownKeys([...[1, , 2]]));
解析
- Reflect.ownKeys() 返回一个由目标对象自身的属性键组成的数组。
console.dir([]); // 可以看到里面只有length属性
console.dir([,]); // 同上
console.dir([1, , 2]); // 数组为:[1, empty, 3] {0: 1, 2: 2, length: 3}, 则有三个属性
console.dir([...[1, , 2]]); // 使用扩展运算符,数组会被填充,变成 [1, undefined, 2]
setTimeout(0ms)
setTimeout(() => {
console.log(2);
}, 2);
setTimeout(() => {
console.log(1);
}, 1);
setTimeout(() => {
console.log(0);
}, 0);
解析
setTimeout 每次调用定时器有个最小间隔是 4ms
2ms足以让其他任务被推送到它之前的队列中,然而1ms是不够的,按照顺序执行被推送,所以先推 1,再到 0,最后才是 2不同浏览器不同表现机制,因为底层实现可能不同。这里只针对 google 浏览器分析。
结果为:1 -> 0 -> 2
Proxy II
class Dev {
#name;
constructor(name) {
this.#name = name;
}
get name() {
return this.#name;
}
}
const dev = new Dev('BFE');
console.log(dev.name);
const proxyDev = new Proxy(dev, {});
console.log(proxyDev.name);
解析
class Dev {
#name; // 私有变量
constructor(name) {
this.#name = name;
}
get name() {
return this.#name;
}
}
const dev = new Dev('BFE');
console.log(dev.name); // 通过调用get name 拿到
const proxyDev = new Proxy(dev, {}); // 代理dev这个对象
console.log(proxyDev.name); // 此时读的是代理完后的对象,不允许读取私有变量,报错
思考 🤔:怎么样才可以拿到呢?
可以通过反射拿到
const proxyDev = new Proxy(dev, {
get(target, key) {
return Reflect.get(target, key);
},
});
console.log(proxyDev.name);
const obj = {
dev: 'bfe',
a: function() {
return this.dev;
},
b() {
return this.dev;
},
c: () => {
return this.dev;
},
d: function() {
return (() => {
return this.dev;
})();
},
e: function() {
return this.b();
},
f: function() {
return this.b;
},
g: function() {
return this.c();
},
h: function() {
return this.c;
},
i: function() {
return () => {
return this.dev;
};
},
};
console.log(obj.a());
console.log(obj.b());
console.log(obj.c());
console.log(obj.d());
console.log(obj.e());
console.log(obj.f()());
console.log(obj.g());
console.log(obj.h()());
console.log(obj.i()());