从JS对象开始_谈一谈究竟什么是“不可变数据”和函数式编程

摘要:JS中的对象是那么美妙:我们可以随意复制他们,改变并删除他们的某项属性等。但是要记住一句话: “伴随着特权,随之而来的是更大的责任。” (With great power comes great responsibility)

作为前端开发者,你会感受到JS中对象(Object)这个概念的强大。我们说“JS中一切皆对象”。最核心的特性,例如从String,到数组,再到浏览器的APIs,对象这个概念无处不在。这里你可以了解到JS Objects中的一切。

同时,随着React的强势崛起,不管你有没有关注过这个框架,也一定听说过一个概念—不可变数据(immutable.js)。究竟什么是不可变数据?这篇文章会从JS源头—对象谈起,让你逐渐了解这个函数式编程里的重要概念。

JS中的对象是那么美妙:我们可以随意复制他们,改变并删除他们的某项属性等。但是要记住一句话:

“伴随着特权,随之而来的是更大的责任。”

(With great power comes great responsibility)

的确,JS Objects里概念太多了,我们切不可随意使用对象。下面,我就从基本对象说起,聊一聊不可变数据和JS的一切。

这篇文章缘起于Daniel Leite在本月16日的文章:Things you should know about Objects and Immutability in JavaScript,我进行了翻译,并改写了用到的例子,以及进行了大量更多的扩展。

可变和共享是万恶之源

不可变数据其实是函数式编程相关的重要概念。相对的,函数式编程中认为可变性是万恶之源。但是,为什么会有这样的结论呢?

这个问题可能很多程序员都会有。其实,如果你的代码逻辑可变,这并不是“政治错误”的。比如JS中的数组操作,很对都会对原数组进行直接改变,这当然并没有什么问题。比如:

let arr = [1, 2, 3, 4, 5];

arr.splice(1, 1); // 返回[2];

console.log(arr); // [1, 3, 4, 5];

这是我们常用的“删除数组某一项”的操作。好吧,他一点问题也没有。

问题其实出现在“滥用”可变性上,这样会给你的程序带来“副作用”。先不必关心什么是“副作用”,他又是一个函数式编程的概念。

我们先来看一下代码实例:click.aliyun.com/m/24142/

const student1 = {    school: 'Baidu',    name: 'HOU Ce',    birthdate: '1995-12-15',}const changeStudent = (student, newName, newBday) => {    const newStudent = student;    newStudent.name = newName;    newStudent.birthdate = newBday;    return newStudent;}const student2 = changeStudent(student1, 'YAN Haijing', '1990-11-10');// both students will have the name propertiesconsole.log(student1, student2);// Object {school: "Baidu", name: "YAN Haijing", birthdate: "1990-11-10"} // Object {school: "Baidu", name: "YAN Haijing", birthdate: "1990-11-10"}

我们发现,尽管创建了一个新的对象student2,但是老的对象student1也被改动了。这是因为JS对象中的赋值是“引用赋值”,即在赋值过程中,传递的是在内存中的引用(memory reference)。具体说就是“栈存储”和“堆存储”的问题。具体图我就不画了,理解不了可以单找我。


原文链接

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

友情链接更多精彩内容