发现一种反模式写法,问问大家的意见

2018-12-03 01:00:58 +08:00
 autoxbc

有如下一小段代码,能否发现这里有什么问题?

const math = {
    sin(val){
        return Math.sin(val);    
    },
    cos(val){
        return Math.cos(val);    
    },
    tan(val){
        const sin = this.sin ;
        const cos = this.cos ;
        return sin(val)/cos(val);    
    },
};

一个粗心的程序员可能会这么续写

const { sin , cos , tan } = math ;
console.log( tan(.5) );

这里就会报错了,因为 tan 方法内部需要的 this 对象在解构赋值的时候丢失了。要想正确使用,必须把代码写成这样的丑陋形式

let { sin , cos , tan } = math ;
[ sin , cos , tan ] = [ sin , cos , tan ].map( e => e.bind(math) );
console.log( tan(.5) );

不过,其实只要在开始的时候,把这两行

const sin = this.sin ;
const cos = this.cos ;

写成

const sin = math.sin ;
const cos = math.cos ;

这样,就消除了隐患。显然,对于 tan 方法,动态绑定 this 对象是没有意义的,因为这个值既不会也不允许改变

总结一下就是,this 是针对动态绑定需求设计的,如果没有这个需求,就不要强行使用,哪怕表面上看上去很优雅

6370 次点击
所在节点    JavaScript
35 条回复
tommyZZM
2018-12-03 12:09:13 +08:00
正确的做法是这样。

```
function sin(val) {
return Math.sin(val);
}

function cos(val) {
return Math.cos(val);
}

function tan(val) {
return sin(val)/cos(val);
},

const math = {
sin, cos, tan
};
```

什么`this`啊, `Function.prototype.bind`啊其实都是糟粕,能不用就不用
tommyZZM
2018-12-03 12:14:15 +08:00
有一个很核心的思路是,尽可能降低函数对外部环境的隐式依赖,同时函数执行时不应该隐式地影响外部环境。

函数之间的关联应该是通过参数的传入联系起来的。

使用了 this 实际上就依赖了调用环境上下文,是一种不好的做法。
no1xsyzy
2018-12-03 13:31:17 +08:00
@ChefIsAwesome 对啊,这个明显是函数式写法啊,为什么要加 this
no1xsyzy
2018-12-03 13:34:45 +08:00
“论如何同时激怒两拨人”
写一个函数式的代码,并且用上 this 并开始谈论对象。

----

const sin = this.sin ;
const cos = this.cos ;

这两行直接删去即可。
66beta
2018-12-03 13:52:21 +08:00
js 严格来讲没有“对象”
class 也只是模拟,将来指不定就成了糟粕
marcong95
2018-12-03 15:29:23 +08:00
@66beta js 是没有类吧,js 无处不在的对象,你总不能说那是个哈希表吧
autoxbc
2018-12-03 15:37:00 +08:00
@no1xsyzy #24 删去能运行刚好是碰运气,后面写成 const { tan } = math 不引入 sin cos 就无效了
66beta
2018-12-03 18:37:50 +08:00
@marcong95 你说的对,我话不严谨,是 OOP 里的 oo
mskf
2018-12-03 19:40:38 +08:00
你是说静态方法只能在静态方法中被引用吗
rabbbit
2018-12-03 20:17:35 +08:00
royzxq
2018-12-03 23:08:35 +08:00
意义不明。
zealot0630
2018-12-04 06:06:21 +08:00
楼主对 OO 的理解有严重问题,OO 设计中,成员函数是放在 prototype 或 meta 里面,而不是对象里面。
cyssxt
2018-12-04 08:16:59 +08:00
math 本来就封装好的 为什么再来一次
nullcc
2018-12-04 08:43:42 +08:00
说 JS this 恶心的应该是那些完全不理解 JS 对象模型的人
zealot0630
2018-12-04 19:04:44 +08:00
@nullcc

JS 的 this 是恶心,这点没得洗,都是历史遗留的包袱。

this 现在大部分情况作为函数的一个额外参数使用,而不是用于调用成员函数,访问成员变量。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/513664

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX