面向对象的链式调用

Posted y雪莉

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了面向对象的链式调用相关的知识,希望对你有一定的参考价值。


1、 对象的链式调用

function Chain(){
  this.n=0;//属性不一定一开始的时候全部都要初始化
  this.fn1=function(_obj){//this指向  new Chain()实例化的对象
    alert(this.n++);//注意:alert(this.n++)与this.fn1中的this 不一定指向的对象是一样的
    return this;
  }
  this.fn2=function(){//同上
    alert(this.n++);//注意:alert(this.n++)与this.fn1中的this 不一定指向的对象是一样的
    return this;
  }
}

var _chain1 = new Chain();
var _chain2 = new Chain();
_chain1.fn1().fn2();//依次弹出 0 , 1
_chain2.fn2().fn1();//依次弹出0 , 1
_chain1.fn1();//弹出 0
_chain2.fn2().fn1().fn2();//依次弹出 2 , 3 , 4(注意:由于前面的_chain2.fn2().fn1())

2、此代码能解决链式调用,但不能解决顺序执行

function Asynchronous(){
  var _self=this;

//由于ajax的回调函数(callBack),this的指向指向window对象下,要想this指向new Asychronous()实例化对象,需要用_self=this,指向实例化对象
  this.visitJson1=function(){
    ajaxRequest("post","json1.json",true,null,function(data){
      alert(data);
    });
  }
  this.visitJson2=function(){
    ajaxRequest("post","json2.json",true,null,function(data){
      alert(data);
    });
  }
  this.visitJson3=function(){
    ajaxRequest("post","json3.json",true,null,function(data){
      alert(data);
    });
  }
}
var _async=new Asynchronous();
_async.visitJson1().visitJson2().visitJson3();//弹出的结果也不一定按照json1,json2,json3输出,由于ajax异步,不能同步输出(即顺序输出)

//正确的如下  (封装的ECMAScript 6中的promise函数)

function Asynchronous(fn){

  this.list = [fn];//把promise当中所有的then内回调函数添加到数组中;之所以用数组,因为ajax是一个不确定什么时候执行完的机制,是异步的,

  //要想要每个函数同步输出(顺序输出),需要把函数它们放进一个数组里面,依次执行
  this.state = 0;//默认为回调函数未完执行成状态
  this.n = 0;//作用:标记应该执行第几个回调函数
  /**
  * then作用:只是把回调函数存到数组当中,然后等待被调用。
  */
  this.then = function(fx){
    this.list.push(fx);
    return this;
  }
  /**
  * 等待被resolve方法按顺序调用,调用后执行数组中的特定的方法
  */
  this.exec = function(n){
    if(this.state == 1){
      this.state == 0;//由于以后有出错 的属性 ,故需要state状态
      this.fm = this.list[n];//注意:只将function赋值给this.fm,由于this.list[n]数组也是一个对象,this指向数组的某一项,达不到this指向实例化对象
      this.fm();
    }
  }
  /**
  * 由回调函数来调用,实例化对象时也自动调用一次;
  */
  this.resolve = function(){//表示执行该回调函数执行完成
    this.state = 1;
    if(this.n < this.list.length){
      this.exec(this.n++);
    }
  }
  this.resolve();
}

new Asynchronous(function(){
  var _self = this;
  ajaxRequest("post","json/json0.json",true,null,function(data){
    alert(data);
    _self.resolve();//由于这是ajax回调函数里面,this的指向的对象是window下,需要改变this的指向,故用_self
  });

}).then(function(){
  var _self = this;
  ajaxRequest("post","json/json1.json",true,null,function(data){
    alert(data);
    _self.resolve();//由于这是ajax回调函数里面,this的指向的对象是window下,需要改变this的指向,故用_self
  });
}).then(function(){
  var _self = this;
  ajaxRequest("post","json/json2.json",true,null,function(data){
    alert(data);
    _self.resolve();//由于这是ajax回调函数里面,this的指向的对象是window下,需要改变this的指向,故用_self
  });
}).then(function(){

  var _self = this;
  ajaxRequest("post","json/json3.json",true,null,function(data){
    alert(data);
    _self.resolve();//由于这是ajax回调函数里面,this的指向的对象是window下,需要改变this的指向,故用_self
  });
});

3、面向对象的继承

 

function Sign(){
  this.account="";
  this.password="";
  this.sign=function(){
    if(this.account=="abcde" && this.password=="123456"){
      alert("登录成功");
    }else{
      alert("登录失败");
    }
  }
}
function Register(){
  this.abc=0;
  this.register=function(){
    this.account="abcde";
    this.password="123456";
  }
}
function Exit(){
  this.exit=function() {
  this.account = null;
  this.password = null;
  }
}
Register.prototype=new Exit();//Register对象拥有Exit对象的实例属性和方法以及原型属性和方法
Sign.prototype=new Register();//Sign对象拥有Register对象的实例属性和方法以及原型属性和方法
var _user=new Sign();
_user.register();
_user.sign();//输出登录成功
_user.exit();
_user.sign();//输出登录失败

 

function main(){
  alert(_user.hasOwnProperty("abc"));//输出false 对象.hasOwnProperty("属性名"); (boolean属性,检测"abc"是不是_user这个对象的实例属性
  alert(Register.prototype.isPrototypeOf(_user));//输出true 对象属性.isPrototypeOf(对象); (boolean属性,检测“Register.prototypeOf”是不是"_user"这个对象的原型属性)
  if("abc" in _user){//无论“abc”是_user这个对象的实例属性还是原型属性,都输出 true,除非“abc”既不是实例属性也不是原型属性(boolean值)
    if(_user.hasOwnProperty("abc")){
      alert("该属性是实例属性");
    }else{
      alert("该属性是原型属性");
    }
  }
}
main();

 

以上是关于面向对象的链式调用的主要内容,如果未能解决你的问题,请参考以下文章

面向对象笔记一

C++封装链式表-链表

js 面向对象的基本概念和基本使用方法

1.1 js 面向对象的基本概念和基本使用方法

spring aop 之链式调用

11面向对象(类抽象类接口作为方法的参数类型和返回值类型链式编程packageimport关键字成员内部类(静态内部类))