新手学js遇到的小问题

代码在这里(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里面还有其他方法没有运行。哎,说了一通,不知各位能否理解。

阅读 3.9k
6 个回答
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

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根本没来得及跑

你都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; 就可以了 也就是你想要的退出当前作用域

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题