首页 > web前端 > js教程 > 正文

利用原型和闭包,完成组件方法

高洛峰
发布: 2016-11-25 13:29:53
原创
1261人浏览过

java代码 
var player = (function(){  
  player = function(){ //这只是个空壳  
  throw new error("can not instantiate a player object.");  
};  
player.min_extended_time = 1;  
player.max_extended_time = 3;  
player._player = false;  
player.getinstance = function(){  
  if(!player._player){  
    alert("init...");  
    player._player = {  
      _name : name,  
      setname : function(name){  
        this._name = name;  
      },  
      tostring : function(name){  
        return "player: " + this._name;  
      }  
    };  
  }  
  return player._player;  
};  
return player; //把修缮完工的player这个组件方法返回  
})();  
 
//var player = new player(); //new player()会抛出异常  
var player1 = player.getinstance();  
var player2 = player.getinstance();  
player2.setname("realplayer");  
alert(player2.tostring()); //输出realplayer 
 终于要定义一个组件方法了,利用原型来实现。看看这样如何:
java代码 
function player(name){  
  player.min_extended_time = 1;  
  player.max_extended_time = 3;  
  this._name = name;  
};  
player.prototype.setname = function(name){  
  this._name = name;  
};  
player.prototype.tostring = function(){  
  return "player: " + this._name;  
};  
 
var player = new player("windowsmediaplayer");  
alert(player.tostring()); //输出windowsmediaplayer  
player.setname("realplayer");  
alert(player.tostring()); //输出realplayer  
alert(player.max_extended_time); 
 
恩,有封装、有常量、也有复写了object的tostring方法,至于继承之类的事情,咱们后面再说,初看看还不错。可是这样的组件方法定义不够优雅,也不够直观,方法都是放在独立的位置定义的,并没有和最开始的组件方法放置在一起,如果能像java那样定义岂不更好?
 
对了,可以用闭包来实现。试试看吧:
java代码 
function player(name){  
  player.min_extended_time = 1;  
  player.max_extended_time = 3;  
  this._name = name;  
  this.setname = function(name){  
    this._name = name;  
  };  
  this.tostring = function(){  
    return "player: " + this._name;  
  };  
};  
 
var player = new player("windowsmediaplayer");  
alert(player.tostring()); //输出windowsmediaplayer  
player.setname("realplayer");  
alert(player.tostring()); //输出realplayer  
alert(player.max_extended_time); 
 
不像groovy里面,闭包做了很大程度上的强化,包括新的语法的支持;javascript的闭包是很简单的闭包,它没有特殊的需要额外学习的语法,任意一个function,里面只要包含未绑定变量,这些变量是在function所属的上下文环境中定义的,那么,这个function就是闭包。顺便罗嗦一句,和闭包相反的,不正是不包含任何未绑定变量的函数式代码吗?
写是写好了,可是转念一想,player应当只有一份,它是单例的,最好我也能像java那样弄一个单例模式出来 :),可是事不遂愿,我没有办法在javascript做一个private的构造器,用这种思路去实现单例模式似乎不可行……
怎么办?
 
然而天无绝人之路,我控制不了你new一个player的对象,我却可以控制你new出来的这个player对象的属性和行为!当你需要使用你new出来的player的对象的时候,你发现根本无法完成,或者它只是一个空壳!真正的东西还是要靠单例中经典的getinstance方法来获得:
java代码 
function player(){  
  throw new error("can not instantiate a player object.");  
}; //这只是个空壳  
 
(function(){ //这才是货真价实的东西  
  player.min_extended_time = 1;  
  player.max_extended_time = 3;  
  player._player = false;  
  player.getinstance = function(){  
    if(!player._player){  
      alert("init...");  
      player._player = {  
        _name : name,  
        setname : function(name){  
          this._name = name;  
        },  
        tostring : function(name){  
          return "player: " + this._name;  
        }  
      };  
    }  
    return player._player;  
  };  
})();  
 
//var player = new player(); //new player()会抛出异常  
var player1 = player.getinstance();  
var player2 = player.getinstance();  
player2.setname("realplayer");  
alert(player2.tostring()); //输出realplayer 
 
好,真不错,单例模式在javascript下也成功实施了——你要胆敢new player();就会抛出一个异常,这样什么也得不到,只有用getinstance方法得到的对象才是真真正正的player对象。上面的代码整个执行的结果,只弹出了一次"init..."的对话框,说明真正的“构造器逻辑”只调用了一次。
 
都做到这份上了,依然有小小的遗憾,player的定义依然被拆分成了两部分,一部分定义空壳,一部分是一个匿名函数来定义player的常量和getinstance方法。这两部分就不能合二为一么?
能。只需要用到一个小小的匿名函数,如果耐心从头看到这里,也一定能理解:
 
到此,终于如释重负,深入理解javascript面向对象,用好原型和闭包这两把锋利的武器,才能写出优秀的前端代码来。有一些同事私下和我交流,后面我尽量贴简洁的代码,希望有面向对象基础和javascript基础的同事都能有所收获。

PatentPal专利申请写作
PatentPal专利申请写作

AI软件来为专利申请自动生成内容

PatentPal专利申请写作 13
查看详情 PatentPal专利申请写作
相关标签:
最佳 Windows 性能的顶级免费优化软件
最佳 Windows 性能的顶级免费优化软件

每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。

下载
来源:php中文网
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
最新问题
开源免费商场系统广告
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新 English
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送
PHP中文网APP
随时随地碎片化学习

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