打劫!交出你的属性值

242 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第34天,点击查看活动详情

目录

今日题

  1. 题目
  2. 分析 昨日题
  3. 题目
  4. 答案
  5. 解析 结语

今日题

题目

实现一个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每日一题》专栏,如果你对本专栏有任何建议,欢迎反馈。如果你对此文章中的题目还有不懂的地方,那么请在评论区留言与大家一起讨论吧。
创作不易,少年,就请留个赞再走吧!