边城

边城 查看完整档案

绵阳编辑西南科技大学  |  (计算机科学与技术) (MBA) 编辑四川凯路威科技有限公司  |  软件总工程师 编辑 ke.sifou.com/course/1650000023477528 编辑
编辑

从事软件开发 20 年,在软件分析、设计、架构、开发及软件开发技术研究和培训等方面有着非常丰富的经验,近年主要在研究 Web 前端技术、基于 .NET 的后端开发技术和相关软件架构。

个人动态

边城 回答了问题 · 4月13日

js变量定义的函数不会“函数提升"吗?

这个问题有意思。

首先,这里报错确实是因为在声明 b 之前使用了 b,用 const 或者 let 都会这样,不用纠结原因,记住不能在声明前使用就对了。

问题是,就算改成 var,仍然会报错,只不过报的是:b 不是函数。

var 可以让变量声明提升,但声明(更准确地说是 Initialization,初始化)只会给它默认的 undefined,赋值为函数,是在使用(调用 b())之后的事情,所以会报这个错。

关注 4 回答 4

边城 回答了问题 · 4月6日

解决请问这个是vscode什么主题什么字体

字体应该是 @唯一丶 说的那个,Fira Code。

推荐几款我用过的字体

  • JetBrains Mono
  • Cascadia Code
  • Source Code Pro
  • Hasklig
  • Fira Code
  • Consolas

主题,感觉用默认主题「深色+ (默认深色)」挺好的哒

关注 3 回答 2

边城 赞了回答 · 4月4日

闭包 JS基础 编程题

(function() {

    let foo = function(...args) {
        let argsArr = args

        function _add() {
            argsArr.push(...arguments)
            return _add;

        }
        _add.getValue = function() {
            let sum = argsArr.reduce(function(a, b) {
                return a + b
            })
            console.log(sum)

            return sum
        }
        return _add;
    }
    let f1 = foo(1, 2, 3)
    f1.getValue()
    let f2 = foo(1)(2, 3)
    f2.getValue()

    let f3 = foo(1)(2)(3)(4)
    f3.getValue()
}
)()

关注 3 回答 2

边城 回答了问题 · 4月4日

闭包 JS基础 编程题

  • 根据结果是通过 f1.getValue() 来取值,说明 foo() 返回一个对象
  • 根据结果 foo(1)(...) 说明 foo() 返回一个函数,可以理解为参数只有 1 个时返回函数
  • 根据结果 foo(...)(4).getValue() 说明 foo() 在参数只有1 个的时候也可能返回对象

综上,foo() 返回一个带额外属性(.getValue)的函数。

  • 当它作为一个函数使用的时候,其行为和 foo() 是一致的,可以考虑递归调用 foo()
  • 当它作为对象的时候,需要通过 getValue() 返回计算结果,所以这个结果可以在 getValue() 中计算出来,也可以作为一个对象状态(属性)保存起来
  • 由于存在函数连调 foo()(),而且后面的调用会累加前面的结果,所以上面一条中提及的计算结果用状态保存比较好,即可以用于后面的计算,也可以通过 getValue() 返回出去

综上分析:

var foo = function (...args) {
    // 函数,是将当前状态值和参数累加
    const add = (...moreArgs) => foo(add.sum, ...moreArgs);
    
    // sum 状态是当前参数的和
    add.sum = args.reduce((s, n) => s + n, 0);
    
    add.getValue = () => add.sum;
    return add;
}

这个问题的关键点不在于闭包(当然会用到闭包),而是柯里化的过程分析。

不过如果你想深入了解闭包可以看看这篇:还搞不懂闭包算我输(JS 示例)

@circle 的答案比我的简单,更容易理解。他那个是闭包实现的答案,更符合题主要求!把那个答案改写一下,不保存参数列表,直接保存中间结果是这样:

var foo = function (...args) {
    let sum = 0;

    const add = (...more) => {
        sum = more.reduce((s, n) => s + n, sum);
        return add;
    };
    add.getValue = () => sum;

    add(...args);
    return add;
}

关注 3 回答 2

边城 回答了问题 · 4月4日

解决关于 typescript 中的 replace

String.prototype.replace 定义了几个重载,这里涉及到的是

  • replace(s: string | RegExp, r: string)
  • replace(s: string | RegExp, replacer: (substring: string, ...args: any[]) => string

很遗憾它并没有定义这样一个重载:

replace(
    s: string | RegExp,
    r: string | (substring: string, ...args: any[]) => string
)

所以直接给一个 string | (substring: string, ...args: any[]) => string 类型的值作为第二个参数是不行的,应该按情况区分开来

    return syntax.reduce((t, p) => {
        return typeof p[1] === "string"
            ? t.replace(p[0], p[1])  // 这里 p[1] 明确是 string
            : t.replace(p[0], p[1])  // 这里 p[1] 明确是 (...) => string
    }, this.text)

如果把参数从数组里拆出来,VSCode 里可以看到明确的类型提示:

image.png

实际上在写代码的时候,为了运行时少做一次判断,可以这样写

强制使用 any 来绕过类型检查,但是注释里要说清楚这样的原因
    // NOTE 明确 p[1] 是 String.prototype.replace 第 2 个参数可接受的类型,不存在例外
    return syntax.reduce((t, p) =>t.replace(p[0], p[1] as any), this.text)

关注 2 回答 1

边城 回答了问题 · 4月4日

解决不懂就问,用 setTimeout 简单实现 setInterval 的问题

如果把输出写得详细一点,加上时间信息

    let timer;
    const _setInterval = (cb, time) => {
        timer = setTimeout(() => {
            cb()
            _setInterval(cb, time)
        }, time);
    }

    _setInterval(() => {
        const now = Date.now();
        console.log('count', now, now - start);
    }, 1000)

    setTimeout(() => {
        clearTimeout(timer)
    }, 3001);

    const start = Date.now();
    console.log("start: ", start);

会发现输出并不是精确的 1000 毫秒延时

start:  1617522317036
count 1617522318045 1009
count 1617522319051 2015

用原生的 setInterval() 会更准确一些(因为模拟的 cb() 处理业务会花一些时间),但仍然可能会有非常小的误差的。

关注 3 回答 2

边城 赞了回答 · 4月4日

解决Chrome怎么阻止JS删除DOM内容?

实现不了。那么考虑考虑其他的手段,比如说clone一份。然后去重之类的操作。

MutationObserver 能监听改变

image.png

关注 5 回答 4

边城 回答了问题 · 4月3日

合并数组,取相应的key并传参,详细看正文,求解

方法一

@林枫 的方法,只不过里面有一点需要改进:不要在 b.map 循环里每次去取 Object.keys(a[0]),提前一次取好重复用就行。

另外,reduce 很好,效率也不错,不过从语法上来说,可以用 map + Object.fromEntries() 来写逻辑会更清楚

const res = (() => {
    const keys = Object.keys(a[0]);
    return b.map(it => Object.fromEntries(keys.map(key => [key, it[key]])));
})();
console.log(res);

方法二「推荐」

说实在的,处理数据我还是比较喜欢用 Lodash

import _ from "lodash";
const result = (() => {
    const keys = Object.keys(a[0]);
    return b.map(it => _.pick(it, keys));
})();

console.log(result);

方法三

这种方法直接修改原数据,将多余的属性删除掉

const result2 = (() => {
    const keys = new Set(Object.keys(a[0]));
    b.forEach(it =>
        Object.keys(it)
            .filter(key => !keys.has(key))
            .forEach(key => delete it[key])
    );
    return b;
})();

console.log(result2);

对于当前这个问题,由于 b 中的属性固定,可以提前把需要删除的 keys 算好,

const result3 = (() => {
    const removeKeys = (keys => {
        Object.keys(a[0]).forEach(key => keys.delete(key));
        return keys;
    })(new Set(Object.keys(b[0])));

    b.forEach(it => removeKeys.forEach(key => delete it[key]));
    return b;
})();

console.log(result3);

关注 4 回答 2

边城 回答了问题 · 4月3日

解决Chrome怎么阻止JS删除DOM内容?

删除行为是在代码里吧,找到相关的代码,去掉就好了

关注 5 回答 4

边城 回答了问题 · 4月3日

小白求助,express的get请求发送失败什么原因?

app.get('/updateuser/:userid/:userphone/:username:/:userpassword/:useremail'
//                                               ^ 这里多了一个冒号

看看是不是这个冒号的原因

关注 2 回答 1

认证与成就

  • 认证信息 软件总工程师
  • SegmentFault 讲师
  • 获得 5268 次点赞
  • 获得 79 枚徽章 获得 5 枚金徽章, 获得 38 枚银徽章, 获得 36 枚铜徽章

擅长技能
编辑

开源项目 & 著作
编辑

  • Viyi.Util

    .NET 的数据格式处数据转换工具

  • TS/JS版俄罗斯方块

    《JavaScript/TypeScript 版俄罗斯方块》系列文章的源码,https://segmentfault.com/a/1190000006919702,https://segmentfault.com/a/1190000007167312

  • ContactDemo

    《Cordova+AmazeUI+React 做个通讯录》系列文章 Demo。 https://segmentfault.com/a/1190000003786037, http://segmentfault.com/a/1190000003827034

  • jNs

    jNs 是一具有命名空间概念的 JavaScript 模块管理工具。与 Sea.js 和 ReqireJS 等模块管理工具不同,jNs 只管理命名空间及模块的定义和使用,而不负责加载,非常适合发布合并 JavaScript 代码的 Web 项目,比如使用了 ASP.NET Web Optimization Framework 提供的 Script Bundle 功能的 ASP.NET 项目,以及使用 UglifyJS 压缩合并脚本的项目等。

注册于 2014-09-09
个人主页被 57.9k 人浏览