持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第34天,点击查看活动详情
目录
今日题
题目
实现一个watch函数,该函数默认监听要监听的对象下面的value属性
作用:
const a = {
value: 20
}
// 第一个参数:要监听的对象, 第二个参数:发生变化要触发的函数,触发的函数有俩参数:前一个值和新的值
watch(a, (oldValue, newValue) => {
console.log(`属性发生变化, 原值:${oldValue}, 新值:${newValue}`);
})
a.value = 20 // 触发监听函数
分析
本题主要使用JS中的一种技术,叫数据代理(数据劫持) 关于既可以做特定属性的数据代理且不用重新赋值的可以使用Object.defineProperty
小例子
let a = "10";
let obj = {
a
}
Object.defineProperty(obj, "a", {
get() {
return a;
},
set(value) {
a = value;
}
})
console.log(obj.a); // "10"
obj.a = "20";
console.log(a); // "20"
这里面,对变量obj做了一波数据代理。
当想要获取属性a则会触发get()函数(getter),该函数的返回值就是这个属性的值。
当修改属性a的值的时候就会触发set()函数(setter),新的值会当作set函数的第一个参数。
这样的操作就叫做数据代理
通过这样的操作我们就可以实现监听了
昨日题
题目
实现数组的join方法
答案
Array.prototype._join = function (sep = ',') {
var i = -1, result = '', len = this.length
var getValue = v => v === undefined || v === null ? '' : v
while (++i < len - 1) result += getValue(this[i]) + sep
result += getValue(this[i])
return result
}
解析
首先是声明三个变量i(while为了后面的++i, 所以不是从0开始,而是从-1开始), result(要接收拼接的字符串),len数组长度,将数组的长度属性变成一个变量,这操作是一种优化,目的是为了再后面循环中不需要重复的去获取length属性
getValue函数,验证数组的元素是否为空
引用while循环拼接数组中的元素,每位元素都经过getValue的验证,再拼接上参数(每个元素中间的间隔字符),循环的结束位置是在数组的倒数第一个(该元素不会经过while循环中的拼接)
而是再最后代码要返回出去的时候做了一次末尾的拼接,注意,这次拼接没有携带上每个元素中间的间隔字符,因为结尾元素后面不需要间隔字符
[1, 2, 3, 4].join("_") // 1_2_3_4
结语
此文章已收录至《JavaScript每日一题》专栏,如果你对本专栏有任何建议,欢迎反馈。如果你对此文章中的题目还有不懂的地方,那么请在评论区留言与大家一起讨论吧。创作不易,少年,就请留个赞再走吧!