从一个组件的实现来深刻理解JS中的继承

时间:2017-11-22 15:32

推广 | 令人窒息的奖品等你―2016最权威的全球开发者调研

其实,无论是写什么语言的程序员,最终的目的,都是把产品或代码封装到一起,提供接口,让使用者很舒适的实现功能。所以对于我来说,往往头疼的不是写代码,而是写注释和文档!如果接口很乱,肯定会头疼一整天。

从一个组件的实现来深刻理解JS中的继承

JavaScript 最初是以 Web 脚本语言面向大众的,尽管现在出了服务器端的 nodejs,但是单线程的性质还没有变。对于一个 Web 开发人员来说,能写一手漂亮的组件极为重要。GitHub 上那些开源且 stars 过百的 Web 项目或组件,可读性肯定非常好。

从一个例子来学习写组件

组件教程的参考来自于 GitHub 上,通俗易懂,链接。

要实现下面这个功能,对一个 input 输入框的内容进行验证,只有纯数字和字母的组合才是被接受的,其他都返回 failed:

从一个组件的实现来深刻理解JS中的继承

全局变量写法

这种写法完全没有约束,基本所有人都会,完全没啥技巧:

// html <input type="text" id="input"/> // javascript var input = document.getElementById("input"); function getValue(){   return input.value; } function render(){   var value = getValue();   if(!document.getElementById("show")){     var append = document.createElement('span');     append.setAttribute("id", "show");     input.parentNode.appendChild(append);   }   var show = document.getElementById("show");   if(/^[0-9a-zA-Z]+$/.exec(value)){     show.innerHTML = 'Pass!';   }else{     show.innerHTML = 'Failed!';   } } input.addEventListener('keyup', function(){   render(); });  

缺点自然不用多说,变量没有任何隔离,严重污染全局变量,虽然可以达到目的,但极不推荐这种写法。

对象隔离作用域

鉴于以上写法的弊端,我们用对象来隔离变量和函数:

var obj = {   input: null,   // 初始化并提供入口调用方法   init: function(config){     this.input = document.getElementById(config.id);     this.bind();     //链式调用     return this;   },   // 绑定   bind: function(){     var self = this;     this.input.addEventListener('keyup', function(){       self.render();     });   },   getValue: function(){     return this.input.value;   },   render: function(){     var value = this.getValue();     if(!document.getElementById("show")){       var append = document.createElement('span');       append.setAttribute("id", "show");       input.parentNode.appendChild(append);     }     var show = document.getElementById("show");     if(/^[0-9a-zA-Z]+$/.exec(value)){       show.innerHTML = 'Pass!';     }else{       show.innerHTML = 'Failed!';     }   } } window.onload = function(){   obj.init({id: "input"}); }  

相对于开放式的写法,上面的这个方法就比较清晰了。有初始化,有内部函数和变量,还提供入口调用方法。

新手能实现上面的方法已经很不错了,还记得当初做百度前端学院题目的时候,基本就是用对象了。

不过这种方法仍然有弊端。obj 对象中的方法都是公开的,并不是私有的,其他人写的代码可以随意更改这些内容。当多人协作或代码量很多时,又会产生一系列问题。

函数闭包的写法

var fun = (function(){   var _bind = function(obj){     obj.input.addEventListener('keyup', function(){       obj.render();     });   }   var _getValue = function(obj){     return obj.input.value;   }   var InputFun = function(config){};   InputFun.prototype.init = function(config){     this.input = document.getElementById(config.id);     _bind(this);     return this;   }   InputFun.prototype.render = function(){     var value = _getValue(this);     if(!document.getElementById("show")){       var append = document.createElement('span');       append.setAttribute("id", "show");       input.parentNode.appendChild(append);     }     var show = document.getElementById("show");     if(/^[0-9a-zA-Z]+$/.exec(value)){       show.innerHTML = 'Pass!';     }else{       show.innerHTML = 'Failed!';     }   }   return InputFun; })(); window.onload = function(){   new fun().init({id: 'input'}); }