灵活的javaScript
通常我们不像下面这样声明函数,因为会创建很多全局变量。
function checkName() { // code }
function checkEmail() { // code }
所以,我们可以用一个对象将变量收编。
var checkObj = { checkName: function () { // code }, checkEmail: function() { // code } }
// 调用
checkObj.checkName();
checkObj.checkEmail();
当然,我们也可以先声明一个对象,然后给它添加方法,调用方式同上面一样。
var checkObj = function () {};
checkObj.checkName = function () {
// code
};
checkObj.checkEmail = function() {
// code
};
但是,当别人有需要用我们上面那些方法时就有些麻烦了。因为这个对象不能复制一份,或者说这个对象类在使用new关键字创建对象时,新创建的对象是不能继承这些方法的。
如果只是想简单的复制下对象,我们可以将这些方法放在一个函数对象中,这样每次调用调用checkObj这个函数的时候,就会返回一个新的包含这些方法的对象,如下:
var checkObj = function () { return {
checkName: function () {
// code
},
checkEmail: function() { // code
}
}
}
// 调用
var obj = checkObj();
obj.checkName();
但是,上述方式并不是一个真正类的创建方式,所以我们将其稍微改造一下:
var CheckObj = function () { this.checkName = function () { // code }; this.checkEmail = function () { // code }; }; // 调用 var obj = new CheckObj(); obj.checkName();
然而,这种方式有时候造成的消耗是很奢侈的,因为我们在使用new关键字创建实例的时候,每个实例都会对this上的属性进行复制,因此会造成每个实例都会拥有自己的一套方法,
所以我们有必要改进一下。将这些方法都挂在到原型上,这样每个实例所有的方法就都是同一个了,因为它们都要依赖prototype依次查找,找到的方法都会是同一个,
即CheckObj类的原型对象上,如下:
var CheckObj = function () {}; CheckObj.prototype.checkName = function () { // code }; CheckObj.prototype.checkEmail = function () { // code }; // 调用 var obj = new CheckObj(); obj.checkName();
这种方式要将protoype写好多遍,可以像下面这样做:
var CheckObj = function () {}; CheckObj.prototype = { checkName: function () { // code }, checkEmail: function () { // code }; }; // 调用 var obj = new CheckObj(); obj.checkName();
但使用这种方式要注意,一定不要和前面那种混用,后者为对象原型对用赋值新对象的这种方式如果用在前者为原型对象添加方法这种方式之后,后者将会覆盖前者。
此时,我们每调用一个方法,都要写一遍示例对象(如obj),我们还可以继续改进,在每个方法末尾将当前对象返回,在JavaScript中,当前对象就是this,
所以,我们可以在函数末尾将this返回。
var CheckObj = function () {}; CheckObj.prototype = { checkName: function () { // code return this; }, checkEmail: function () { // code return this; }; }; // 调用 var obj = new CheckObj(); obj.checkName().checkEmail();
一款JavaScript框架,其实就是里面为我们封装了很多方法,最大的特点就是对源生对象的拓展,比如如果想给每个函数添加一个检测姓名的方法,可以这么做:
Function.prototype.checkName = function () { // code };
// 调用
var fn = function () {};
f.checkName();
但这种平时开发中是绝对不允许的,因为这样会污染原生对象Function,那要怎么做呢?
我们可以抽象一个统一添加方法的方法:
Function.prototype.addMethod = function (name, fn) { this[name] = fn; }; var methods = function () {}; methods.addMethod('checkName', function () { console.log('checkName'); }); methods.addMethod('checkEmail', function () { console.log('checkEmail'); }); methods.checkName(); methods.checkEmail();
同样,我们可以使用链式添加的方式:
Function.prototype.addMethod = function (name, fn) { this[name] = fn; return this; }; var methods = function () {}; methods.addMethod('checkName', function () { console.log('checkName');
return this; }).addMethod('checkEmail', function () { console.log('checkEmail');
return this; }); methods.checkName().checkEmail();
按照上述方式我们使用的是函数调用方式,对于习惯类式调用的我们可以稍微简单改一下:
Function.prototype.addMethod = function (name, fn) { this.prototype[name] = fn; // 挂载到原型上 return this; }; var Methods = function () {}; Methods.addMethod('checkName', function () { console.log('checkName'); return this; }).addMethod('checkEmail', function () { console.log('checkEmail'); return this; }); var m = new Methods(); m.checkName().checkEmail();
JavaScript是不是很灵活呢? *(^_^)*~~~