javascript 模拟函数指针
来源:uedmagazine 发布时间:2009-09-19 18:02:00
这个是今年年初写的一篇,拿出来温习下。
指针让程序结构变得混乱,也让程序执行效率提高,因此在oo的语言中不提倡指针的使用,使得程序结构清晰易读可维护,特别是在工程中,降低了人员流动带来的代码维护成本。在java和js中甚至将指针完全禁止,只提供引用。但指针毕竟是引用的基础,指针使用恰当也会提高程序的效率,像我这种之前一直生活在 c和c++中,转型到js之后没有指针的编码风格总有些不习惯,这也让我在设计js的逻辑的时候经常卡壳,并深深怀念当年在指针的海洋中飘来飘去的感觉。
语言有语言的优势,也有它的劣势,语言也总是用hack的方法来弥补劣势,c中的goto和js中的eval都是这种例子。js的优点是语义丰富逻辑清晰语法灵活多变,函数操作是最基础的操作,但有时会遇到很多困惑,比如函数交换:
现在有两个函数:
var fun1 = function(str){
alert('执行函数1,参数:'+str);
};
var fun2 = function(str){
alert('执行函数2,参数'+str);
};
交还这两个函数,最简单的方法是:
var _o=fun1;
fun1=fun2;
fun2=_o;
能否将函数交换操作封装到函数中呢?比如:
var changefun = function(fun1,fun2){
var _o=fun1;
fun1=fun2;
fun2=_o;
};
最简单的想法是将fun1和fun2的指针传递到changefun中,让changefun完成函数指针的交换,在js中这是不可能的,js没有指针,而且传递到changefun中的函数都会被闭包起来,脱离原有的命名空间。但我可以这样:
var changefun = function(s1,s2){
eval('var _o = '+s1+';'+s1+' = '+s2+';'+s2+' = _o;');
};
传递函数名给changefun,在changefun中构造交换的代码再执行,虽然changefun里的变量都被闭包住,但是参数是函数名是字符串,这样changefun中构造好的代码中的s1和s2却可以伸展到以外的命名空间,只要在changefun同一级的命名空间中存在fun1和fun2,代码就会被正确执行。比如这样一段代码就会被正确执行:
var fun1 = function(str){
alert('执行函数1,参数:'+str);
};
var fun2 = function(str){
alert('执行函数2,参数'+str);
};
var changefun = function(s1,s2){
eval('var _o = '+s1+';'+s1+' = '+s2+';'+s2+' = _o;');
};
changefun('fun2','fun1');
fun1('1');
fun2('2');
但是changefun不总是和被交换的函数在同一个命名空间中,例如这样一段代码就不会交换成功:
var changefun = function(s1,s2){
eval('var _o = '+s1+';'+s1+' = '+s2+';'+s2+' = _o;');
};
var myClass1 = function(){
var fun1 = function(str){
alert('执行函数1,参数:'+str);
};
var fun2 = function(str){
alert('执行函数2,参数'+str);
};
return {
init:function(){
changefun('fun2','fun1');
},
fun1:fun1,
fun2:fun2
};
};
var a = new myClass1();
a.init();
a.fun1('1');
a.fun2('2');
对于这种情况,则必须把changefun放到与fun1和fun2同一个根空间下,这样函数交换成功:
var changefun = function(s1,s2){
eval('var _o = '+s1+';'+s1+' = '+s2+';'+s2+' = _o;');
};
var myClass1 = function(){
var fun1 = function(str){
alert('执行函数1,参数:'+str);
};
var fun2 = function(str){
alert('执行函数2,参数'+str);
};
return {
init:function(){
changefun('fun2','fun1');
},
fun1:fun1,
fun2:fun2
};
};
var a = new myClass1();
changefun('a.fun1','a.fun2');
a.fun1('1');
a.fun2('2');


猜你喜欢
- 一直以来都是链接SQL Server数据库服务但是在部署时将很麻烦,所以突发奇想,直接连接到MDF文件,刚开始还很混乱不会连接,后来向导,连
- Python多线程与多进程中join()方法的效果是相同的。下面仅以多线程为例:首先需要明确几个概念:知识点一:当一个进程启动之后,会默认产
- reduce函数原本在python2中也是个内置函数,不过在python3中被移到functools模块中。reduce函数先从列表(或序列
- 在使用python 对wordpress tag 进行细化代码处理时,遇到了调用MySQLdb模块时的出错,由于错误提示和问题原因相差甚远,
- 视频本课程的视频添加盾牌现在,我们的玩家被一颗流星击中就摧毁。这不是很有趣,所以我们要向Player类添加一个shield属性,它是0 -
- 一、使用 Microsoft OLE DB Provider For ODBC 链接MySQL安装MySQL的ODBC驱动MyODBC1、为
- Beautiful Soup 库一般被称为bs4库,支持Python3,是我们写爬虫非常好的第三方库。因用起来十分的简便流畅。所以也被人叫做
- python中zip函数返回一个以元组为元素的列表,其中第 i 个元组包含每个参数序列的第 i 个元素。返回的列表长度被截断为最短的参数序列
- 如何 在Access中选择指定日期前的记录?我知道,在Access中不能使用DateDiff,那么我们怎样才能选择指定日期前的若干记录呢?虽
- Python GUI 库有很多,下面给大家罗列常用的几种 GUI 库。下面介绍的这些GUI框架,能满足大部分开发人员的需要,你可以根据自己的
- 说明1、Task是Future的子类,Task是对协程的封装,我们把多个Task放在循环调度列表中,等待调度执行。2、Task对象可以跟踪任
- 1、Librosaimport librosa filepath = "/Users/birenjianmo/Desktop/le
- 1. 项目背景在python 即时网络爬虫项目启动说明中我们讨论一个数字:程序员浪费在调测内容提取规则上的时间,从而我们发起了这个项目,把程
- 最近导师让我跑模型,生物信息方向的,我一个学计算机的,好多东西都看不明白。现在的方向大致是,用深度学习的模型预测病毒感染人类的风险。既然是病
- 傅立叶级数的介绍我就不说了,自己也是应用为主,之前一直觉得很难懂,但最近通过自己编程实现了一些函数的傅立叶级数展开之后对傅立叶 级数展开的概
- mapmap(function,iterable)x = [1,2,3,4,5]def square(num): return num*nu
- 我们都有过函数调用的经历,那么call调用类实例的过程就跟函数很相似。类的用法很多人都知道了,类实例又是什么呢?可以把类看成一个设计图,类实
- 本文实例讲述了python打开文件并获取文件相关属性的方法。分享给大家供大家参考。具体分析如下:下面的代码通过open函数打开文件,并输出文
- 前言Pytorch、Tensoflow等许多深度学习框架集成了大量常见的网络层,为我们搭建神经网络提供了诸多便利。但在实际工作中,因为项目要
- 解决项目pycharm能运行,在终端却无法运行的问题报 ModuleNotFoundError: No module named '