如题,最近听前端同事讨论 js 的闭包有感,这个帖子想讨论一下语言的命名空间设计,并非单纯局限在闭包问题。标题里写闭包是因为感觉这样比较容易被大家理解。
以下正文
=============
我个人学习 js 的过程中没怎么在意过闭包这个特性,我感觉命名空间逐级继承是一个再自然不过的设计,其他语言中不都是如此设计的?但是旁听别人讨论后发现 js 的命名空间确实跟其他语言不太一样,从设计原因上,似乎 js 的作者希望设计出一种特性能保存函数执行过程中的栈状态,不过我个人感觉上闭包这种使用方法又没有其他语言中生成器之类的特性描述能力强。
从使用角度来说,js 中命名空间的一个特性是子空间可以修改父空间内容,比如
var data = 0
var func = function(){
data = 1
}
func()
console.log(data)
在这段代码中很显然 data 属于“全局变量”而被单个函数的调用过程所修改了。以前在写 js 的时候没注意,感觉自然也没什么奇怪之处。但是仔细想想,平时写其他语言时并不是这么处理的。比如 C 语言中要达到类似效果通常是通过传入指针的方式
#include<stdio.h>
void main(){
int data = 0;
void func(int *p){
*p = 1;
}
func(&data)
printf()
}
类似这样,即函数显然可以访问同级或上级作用域中的变量,但通过一个函数直接修改全局变量的指向是不被允许的。
在 python 当中可能用一些变通的结构
data = [0]
def func(data):
data[0] = 1
或者使用 global 将全局变量暴露在函数中
data = 0
def func(data):
global
data = 2
不过说实话这种描述方式感觉比较局限,虽然理论上使用起来与 js 相当,但我在实际程序中几乎没有使用过 global 或者 nonlocal 之类的特性。
java 当中又回到类似 js 的模式,变量值可以直接被修改了。
============
不禁让人打起一个大大的问号,即为什么这种设计并不统一,有的语言仅可以读取,有的语言可以直接修改。他们都是出于什么目的设计这种特性的?
这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。
V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。
V2EX is a community of developers, designers and creative people.