zoukankan      html  css  js  c++  java
  • 面向对象的链式调用


    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();

  • 相关阅读:
    JavaScript 实现打印操作
    linux-centos7.6设置固定IP网络方法
    VMware网络配置三种网络模式(桥接、NAT、Host-only)
    SVN 执行cleanup报错:Cleanup failed to process the following paths
    word生成目录的pdf
    win10开机后将存在多个系统选择,改为直接进入系统无需选择
    Win10删除或是不显示快速访问中最近使用文件记录
    Dell T30解决报Alert! Cover was previously removed.
    WIN10安装.net报0x800F081F解决方法
    查看SVN当前登录用户
  • 原文地址:https://www.cnblogs.com/shirly77/p/6260389.html
Copyright © 2011-2022 走看看