javascript - 新手学js遇到的小问题
高洛峰
高洛峰 2017-04-10 17:51:29
[JavaScript讨论组]

代码在这里(jsBin):http://jsbin.com/kisime/1/edit?js,console
怎么做可以让函数m2也执行呢?
看了好几个回答者所做回答,好像都没理解我写这段代码的本意。我之所以写这一句:throw new Error('程序结束');,是因为在JavaScript中我没有找到可以想其他语言exit;语句那样直接退出整个程序的语句,所以我这里写抛出一个异常让整个程序退出。我这段代码的功能就是:subApp本身也是一个函数,也可以像普通函数m1和m2那样做use 的参数,然后是怎么正常运行完app.stack里存储的所有方法,也就是说在运行subApp时程序能知道subApp只是app.stack里面的一个方法,而app.stack里面还有其他方法没有运行。哎,说了一通,不知各位能否理解。

高洛峰
高洛峰

拥有18年软件开发和IT教学经验。曾任多家上市公司技术总监、架构师、项目经理、高级软件工程师等职务。 网络人气名人讲师,...

全部回复(6)
PHP中文网
app.use(m1);
app.use(m2);
app.use(subApp);
app();

交换下位置不行么?如果先执行subApp的话,那么app.stack就为空,就会抛出错误,程序就停止了呀,就肯定不会执行m2了。

怪我咯

按题主要求进行了修改,可以实现题主说的用prototype进行查找了。

var createApplication = function(){
  var app = function(){
    console.log('This is app');
    next();
    function next(){
      //console.log('This is next');
      if(app.stack.length > 0){
        app.stack.shift()();
      }
      if(app.stack.length > 0){
        next();
      }else{
        app.stack = app.prototype.stack;
        if(app.stack.length > 0){
          next();
        }else{
          throw new Error('程序结束');
        }   
      }
    }
  };
  app.stack = [];
  app.use = function(argFun){
    this.stack.push(argFun);
  };
  return app;
};
function m1(){
  console.log('this is m1');
}
function m2(){
  console.log('this is m2');
}
var app = createApplication();
var subApp = createApplication();
subApp.prototype = app;
app.use(m1);
app.use(subApp);
app.use(m2);
app();

我现在没搞懂题主为啥要实现这么蹩脚的代码,一个函数数组遍历执行用递归去实现,结束遍历还要退出标致,函数数组中有自己的同类要执行,同类执行完还不能触发程序退出,那么只能让这个函数判断自己是调用者还是被调用者。

题主遇到的是什么场景需要这样的实现,我表示好奇。
---------- 2016.3.24 更新分割线 ----------

app.use(subApp); 把app = 的那个函数对象穿进去了, 执行到这句的时候,stack里面是没有值的。
程序就结束了。

按照题主的意思进行了修改,保留题主本意的情况下解决了程序存在的问题。

var createApplication = function(){
  var app = function(baba){
    console.log('This is app');
    next();
    function next(){
      //console.log('This is next');
      if(app.stack.length > 0){
        app.stack.shift()();
      }
      if(app.stack.length > 0){
        next();
      }else if(baba === app.stack){
        throw new Error('programing end');
      }
    }
  };
  app.stack = [];
  app.use = function(argFun){
    this.stack.push(argFun);
  };
  return app;
};
function m1(){
  console.log('this is m1');
}
function m2(){
  console.log('this is m2');
}
var app = createApplication();
var subApp = createApplication();

app.use(m1);
app.use(subApp);
app.use(m2);
app(app.stack);

把判断程序退出的条件进行了修改,同时app的函数新增一个自己身上属性的参数,这么做就可以避免把自己的stack长度当成判断退出的条件,从而导致外层的stack后续元素无法执行。

之前大家都在回答中指出了程序存在的bug的病理,本质上这种自己引用自己的写法需要区别场景,一般做做深度递归。 而在递归里参入终止后续程序执行的代码就会存在bug隐患。递归一般是执行完返回执行结果,终止程序执行的条件最好写在外面,从可读性来讲也算是编码规范。

迷茫

throw new Error('程序结束'); 阻塞后面函数执行了,去掉或改成 console.log

ringa_lee

app.use(subApp);
这个subApp比m2先跑,触发了自己作用域里的next()

if(app.stack.length > 0){
    app.stack.shift()();
}
if(app.stack.length > 0){
    next();
}else{
    throw new Error('programing end');
}

这个subApp的stack.lenght本来就是0,所以立即抛出Error,程序终止,m2根本没来得及跑

PHP中文网

你都throw new Error()报错了还能execute,那真是奇葩了,
你的代码相当于这个:
var a= function(){

function next(){
  if(a.l.length > 0){
    a.l.shift()();
  }
  if(a.l.length > 0){
    next();
  }else{
    console.log('program terminate? no');
  }
}
 next();

};
a.l = [];
a.use = function(c){

this.l.push(c);

};

function m1(){
console.log('this is m1');
}
function m2(){
console.log('this is m2');
}

var b= a
a.use(m1);
a.use(m2);
a.use(b);
a();

高洛峰

把throw new Error('程序结束'); 改成return; 就可以了 也就是你想要的退出当前作用域

热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 意见反馈 讲师合作 广告合作 最新更新 English
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送
PHP中文网APP
随时随地碎片化学习

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号