Неправильный контекст выполнения функции?
Это правильное поведение. Контекст — то, что перед последней точкой. Нужен другой — в любом случае придется где-то привязывать. Или как написано выше, или так:
this.a2 = new A2({f1:this.ff1.bind(this),f2:this.ff2.bind(this)});

Можно упростить, написав функцию bindAll:
function bindAll(obj,ctx){
  if(arguments.length<2)ctx=obj;
  for(var key in obj)if(typeof obj[key]=='function')obj[key]=obj[key].bind(ctx);
  return obj}

В итоге выйдет что-то в стиле
var A2 = function(params){
  this.f1=params.f1;
  this.f2=params.f2;
  this.name='a2'}
A2.prototype.f3=function(){
  if(this.f1)this.f1()}
a1={
  name:'a1',
  init:function(){
    this.a2=new A2(bindAll({
        f1:function(){console.log(this.name)},
        f2:function(){console.log(this.name)}
      },this));
    }
  }
a1.init();
a1.a2.f3(); //=> a1

Либо передавайте контекст, либо уже привязанные к контексту функции. Другого варианта нет.