一.利用对象收编变量
当我们决定实现某一项功能的时候最简单的其实就是写一个命名函数,然后调用来实现,就像这样:
function checkName(){ //验证姓名 } function checkEmail(){ //验证邮箱 } checkEmail(); checkName();
但是这样一来实际上增加了很多的值为函数全局变量,我们这么写会看的更清楚:
var checkName = function(){ //验证姓名 } var checkEmail = function(){ //验证邮箱 } checkEmail(); checkName();
这样写的功能并没什么问题,但是增加全局变量在多人开发的时候便会产生互相覆盖的问题,并且不易被察觉
最简单的处理方法是,将变量放置在对象里面,通过访问对象属性或方法来执行函数。如下
var CheckObject = { checkName: function(){ //验证姓名 }, checkEmail:function(){ //验证邮箱 } } CheckObject.checkName(); CheckObject.checkEmail();
同样也可以先声明对象,然后往里面添加方法,如下:
var CheckObject = function(){}; CheckObject.checkName = function(){ //验证姓名 } CheckObject.checkEmail=function(){ //验证邮箱 }
这种先声明对象,再添加方法的方式其实很像我们在angular中声明对象的方式,给$scope这个对象添加方法来实现页面和控制器之间的双向绑定。
二.给对象赋予(复制,实例化,链式调用等)功能
当我们创建完方法后还希望这些方法可以重复利用,也就是当我们复制一份(new)对象之后还能继续使用我们之前创建的方法,所以我们需要对对象进一步进行处理。
复制
如果我们只是单纯想要复制对象的方法,我们可以将方法放置在一个函数对象里面,如下:
var CheckObject = function(){ return { checkName:function(){ //验证姓名 }, checkEmail:function(){ //验证邮箱 } } }
我们可以在很多地方看到函数以这样的方式书写,其实它的目的是每次调用函数都会返回一个新的对象,不会造成相互影响,调用的时候可以这样:
var a = CheckObject(); a.checkName();
类
这个函数对象已经实现了复制功能,但是我们每次调用时候的a都是创建出来的新对象,跟原函数对象没有任何关系,并且按照习惯我们在创建新对象的时候通常使用的是new方法,所以我们还需要在修改一下,如下:
var CheckObject = function(){ this.checkEmail=function(){ //验证姓名 }, this.checkEmail = function(){ //验证邮箱 } }
像这样的对象就可以看做是类,所有的方法都是创建再对象上面,调用的时候我们可以使用new关键字来创建,如下:(这种用类创建对象的方法也叫作对类实例化)
var a = new CheckObject(); a.checkEmail();
在这个对象里面,我们将所有的方法通过this来定义,所以使用new实例化的时候,实际上会将类上面this的属性进行复制,这样实际上每个人调用的对象使用的都是一套新的方法。为了减少这种不必要的消耗,我们可以将方法定义在原型上,这样每次创建出来的对象实际上用的是同一套方法,如下:
var CheckObject = function(){}; CheckObject.prototype.checkName = function(){}; CheckObject.prototype.checkEmail = function(){};
或者可以这么写:
var CheckObject = function(){}; CheckObject.prototype = { checkName:function(){}, checkEmail:function(){} };
这两种方式都是在原型上创建方法,不过不能一起用,否则会相互覆盖。使用这种方式定义类的时候调用的方法需要变化一下:
var a = new CheckObject(); a.checkName(); a.checkEmail();
链式调用:
当我们调用的时候就会方法如上,每次都要把创建的方法写一遍。我们要实现像jquery那样的链式调用的话就要给每个方法返回当前的对象,如下:
var CheckObject = function(){}; CheckObject.prototype = { checkName:function(){ return this;}, checkEmail:function(){return this;} };
调用的时候可以这样:
var a = new CheckObject(); a.checkName().checkEmail()
三. 对js原生对象的扩展
其实这些方法在prototype.js里面都已经用到过了,比如我们要对原生对象(js内置的对象类,如Function,Array,Object等)进行扩展,我们可以抽象出一个统一的添加方法(不能直接在原生对象上面进行添加方法,那样会污染原生对象):
Function.prototype.addMethod = function (name, fn){ this[name]=fn; return this; }
添加方法可以这样:(使用返回当前对象的方法来实现链式调用)
var method = new Function(); methods.addMethod('checkName', function(){ return this; }).addMethod('checkEmail', function(){ return this; });
调用方法可以这样
methods.checkName().checkEmail();
当然我们如果要使用面向对象的方法来使用js的话,就需要习惯使用类式的调用方法
var method = function(){}; methods.addMethod('checkName', function(){}).addMethod('checkEmail', function(){}); var m=new Methods(); m.checkName();