Javascript插件开发导读
2016-12-29 21:33
549 查看
为什么要做javascript插件开发?
这个应该是一个必然。因为需要跨时间、空间不同开发人员的协作,代码的重用。具体也就不多说了。
js开发小白一般怎么开发程序?我记得我刚入行是这么写的:
Js代码
![](http://pigkiller.iteye.com/images/icon_star.png)
var a = 1;
var b = 2;
function add(aaa, bbb) {
var result= aaa + bbb;
alert("result == " + result);
}
add(a,b);
add函数很简单,就是计算传入两个数字之和然后alert结果。需求到了后来陆陆续续加上了减法、乘法、除法,我也对应增加了reduce、multiply、divide方法。
所以我的代码变成了以下这个样子:
Js代码
![](http://pigkiller.iteye.com/images/icon_star.png)
var a = 1;
var b = 2;
// 加法
function add(aaa, bbb) {
var result= aaa + bbb;
alert("result == " + result);
}
// 减法
function reduce(aaa, bbb) {
var result= aaa - bbb;
alert("result == " + result);
}
// 乘法
function multiply(aaa, bbb) {
var result= aaa * bbb;
alert("result == " + result);
}
// 除法
function divide(aaa, bbb) {
var result = aaa / bbb;
alert("result == " + result);
}
// 执行加、减、乘、除
add(a, b);
reduce(a, b);
multiply(a, b);
divide(a, b);
突然有一天,小伙伴说哥,你这几个函数我们项目经常用到,可不可以提供出来让我们调用?我说这个简单。于是我把加减乘除的函数单独放置到了一个mathUtil.js文件中,这个文件的内容如下:
Js代码
![](http://pigkiller.iteye.com/images/icon_star.png)
// 加法
function add(aaa, bbb) {
var result= aaa + bbb;
alert("result == " + result);
}
// 减法
function reduce(aaa, bbb) {
var result= aaa - bbb;
alert("result == " + result);
}
// 乘法
function multiply(aaa, bbb) {
var result= aaa * bbb;
alert("result == " + result);
}
// 除法
function divide(aaa, bbb) {
var result = aaa / bbb;
alert("result == " + result);
}
这个时候其实就是进入了最最原始的插件开发了。因为我写的这份代码被跨时间、跨空间供不同开发人员协作使用,这份代码也做了重用,减少了重复劳动。
接下来就是完善插件的过程了。
优化:方法直接暴露在全局作用域,容易命名冲突且通过作用域查找性能消耗大。没有面向对象编程,纯程式化的函数罗列。解决方案:使用对象封装。
对于JavaScript的面向对象的设计使用,这个也是难点,必须坐下来好好说说。
javascript对象的生成方法有2种:
Js代码
![](http://pigkiller.iteye.com/images/icon_star.png)
// 字面量定义
var person1 = {
name: "peter",
age: 18,
sayHello: function() {
alert("hello! I am " + this.name);
}
};
// 创建Object的一个实例
var person2 = new Object();
person2.name = "william";
person2.age = 19;
person2.sayHello = function() {
alert("hello! I am " + this.name);
};
以上虽然能创建对象,但是有个缺点。如果要创建多个对象,就需要重复写以上的代码。为了解决这个问题我们可以使用:
工厂模式:
Js代码
![](http://pigkiller.iteye.com/images/icon_star.png)
// 工厂模式
function createPerson(name, age) {
var o = new Object();
o.name = name;
o.age = age;
o.sayHello = function() {
alert("hello! I am " + this.name);
};
return o;
}
var person1 = createPerson("peter", 18);
var person2 = createPerson("william", 19);
工厂模式已经可以满足一般我们的开发需要了,但是这个也是有点问题。命名不够直接,实现方面也可以简化。怎么弄?使用构造函数模式:
Js代码
![](http://pigkiller.iteye.com/images/icon_star.png)
// 构造函数模式
var Person = function(name, age) {
this.name = name;
this.age = age;
this.sayHello = function() {
alert("hello! I am " + this.name);
}
};
var person1 = new Person("peter", 18);
var person2 = new Person("william", 19);
从工厂模式跨越到了构造模式,跨度有点大,这里解释一下:
相比较工厂模式,构造函数模式有以下不同:
A.没有显式创建对象
B.直接将属性、方法赋予了this对象
C.没有return
这些都是因为在使用new 操作符构造函数模式时经历以下过程:
A.创建一个对象
B.将构造函数的作用域赋给新对象,所以this就指向了这个新对象
C.执行构造函数中的代码,例子中就是赋予新对象属性和方法
D.返回新对象
虽然构造函数模式隐含省略了很多步骤且不怎么好理解。但是使用起来却是简单直接。例如我要创建一个person类,new Person()就得到了(和java的语法简直一模一样啊~32个赞!)。但是要是使用工厂模式,就必须调用createPerson();有时候工厂模式的函数是别的人写的,写成了createHuman,这不逼死强迫症嘛?!
另外一个重要的好处是:使用构造函数模式产生的对象是该函数的实例。怎么讲呢?如果使用工厂模式,得到的person只是Object的实例。而构造函数模式得到的person却是更为具体的Person的实例!当然它同时也是Object的实例。
这个优点在使用instanceof操作符进行实例判断时可以给出我们准确的判断,如果都是工厂模式出来的产品,那么检测结果就是大家都是Object的实例。
在这里,如果不考虑构造函数模式的一些细节问题。这种插件的写法已经可以应用到我们的项目当中了,不知道你们有没有在项目中见到其他人是这么写的?所以我们的mathUtil.js文件就可以写成下面这种样子了:
Js代码
![](http://pigkiller.iteye.com/images/icon_star.png)
function MathUtil() {
// 加法
this.add = function(aaa, bbb) {
var result= aaa + bbb;
alert("result == " + result);
};
// 减法
this.reduce = function(aaa, bbb) {
var result= aaa - bbb;
alert("result == " + result);
};
// 乘法
this.multiply = function(aaa, bbb) {
var result= aaa * bbb;
alert("result == " + result);
};
// 除法
this.divide = function(aaa, bbb) {
var result = aaa / bbb;
alert("result == " + result);
};
}
使用方法:
Js代码
![](http://pigkiller.iteye.com/images/icon_star.png)
// 引用mathUtil.js文件后使用方式:
var mathUtil1 = new MathUtil();
mathUtil1.add(1, 2);
这样以来插件就实现了面向对象的抽象过程,且将插件需要的各种变量封装了起来。
以上的构造函数模式还是有点小问题的,对于一个对技术精益求精的前端开发,这点也是不能容忍的。问题在于mathUtil函数体重的add等方法都是对象(函数也是特殊对象,定义一个函数就相当于实例化了一个对象了)。当new一个MathUtil的实例时,实例中的方法都是一样的,但是重复了。其实这个是没有必要的。怎么办?
最简单粗暴的方式就是把相关的函数提取出来(为了表述方便加入version变量):
Js代码
![](http://pigkiller.iteye.com/images/icon_star.png)
function MathUtil() {
// 版本号
var version = "1.0";
// 加法
this.add = add;
// 减法
this.reduce = reduce;
// 乘法
this.multiply = multiply;
// 除法
this.divide = divide;
}
// 加法
var add = function(aaa, bbb) {
var result= aaa + bbb;
alert("result == " + result);
};
// 减法
var reduce = function(aaa, bbb) {
var result= aaa - bbb;
alert("result == " + result);
};
// 乘法
var multiply = function(aaa, bbb) {
var result= aaa * bbb;
alert("result == " + result);
};
// 除法
var divide = function(aaa, bbb) {
var result = aaa / bbb;
alert("result == " + result);
};
以上的改造后,如果new多个MathUtil的实例时,add函数只有一个实例,那就是指向了和MathUtil平级的那个add函数。其他函数相同情况。
但是从实际操作来讲,还不如消耗一点性能,不将插件的函数提取出来。因为这样一来暴露出来的变量急剧增加,很不好控制。
有没有方案解决这种问题呢?即多个实例的共同方法、对象指向一个,复用方法。答案就是原型模式:
Js代码
![](http://pigkiller.iteye.com/images/icon_star.png)
var MathUtil = function() {};
MathUtil.prototype = {
// 将构造函数置为MathUtil,这里一定要将constructor重新设置回MathUtil,不然会指向Object的构造函数
constructor: MathUtil,
// 版本号
version: "1.0",
// 加法
add: function(aaa, bbb) {
var result= aaa + bbb;
alert("result == " + result);
},
// 减法
reduce: function(aaa, bbb) {
var result= aaa - bbb;
alert("result == " + result);
},
// 乘法
multiply: function(aaa, bbb) {
var result= aaa * bbb;
alert("result == " + result);
},
// 除法
divide: function(aaa, bbb) {
var result = aaa / bbb;
alert("result == " + result);
}
};
以上的原型模式看起来已经比较完美了,但是还是有两个比较突出的问题:
A.无初始化变量入口
B.当属性为Array类型时,会发生属性篡改
对于MathUtil这个函数,无初始化变量入口的意思是在new出一个实例时想直接将version传入,覆盖默认值。但是,以上的设计明显是做不到的。
再说属性篡改问题,为了说明这个问题我们在mathUtil对象中加入一个programmer变量,用来存储开发人员的姓名。
Js代码
![](http://pigkiller.iteye.com/images/icon_star.png)
var MathUtil = function() {};
MathUtil.prototype = {
//省略了其他的代码
//开发人员
programmer: []
};
Js代码
![](http://pigkiller.iteye.com/images/icon_star.png)
// 实例化一个MathUtil,并给programmer里增加一个开发人员姓名
var m1 = new MathUtil();
m1.programmer.push("william");
// 实例化一个MathUtil,没有对programmer进行任何操作的情况下,m2的programmer属性无缘无故就多出来一个"william"
var m2 = new MathUtil();
m2.programmer;
这是由于m1、m2共享了同一个原型对象导致的,而Array属于引用类型,所以就造成了m1的programmer其实和m2的programmer是同一个实例的情况。所以呢,我们就人为地对对象的属性做个分类,如果是函数,我们就统一放到prototype属性指向的实例当中,如果只是非引用类型或者Array类型的属性我们放在构造函数里面。而且我们同时改造构造函数接受参数:
Js代码
![](http://pigkiller.iteye.com/images/icon_star.png)
var MathUtil = function(version, programmer) {
this.name = name;
this.programmer = programmer;
};
MathUtil.prototye = {
// 将构造函数置为MathUtil,这里一定要将constructor重新设置回MathUtil,不然会指向Object的构造函数
constructor: MathUtil,
// 加法
add: function(aaa, bbb) {
var result= aaa + bbb;
alert("result == " + result);
},
// 减法
reduce: function(aaa, bbb) {
var result= aaa - bbb;
alert("result == " + result);
},
// 乘法
multiply: function(aaa, bbb) {
var result= aaa * bbb;
alert("result == " + result);
},
// 除法
divide: function(aaa, bbb) {
var result = aaa / bbb;
alert("result == " + result);
}
};
调用测试的代码:
Js代码
![](http://pigkiller.iteye.com/images/icon_star.png)
// 引用mathUtil.js文件后使用方式:
var m1 = new MathUtil("william",["william"]);
m1.programmer.push("william2");
var m2 = new MathUtil("peter",["peter"]);
m1.programmer.push("peter2");
这个时候m1,m2各自的programmer对应的就是不同数组了。而且还同时具有初始化参数的能力。
以上的写法已经比较完美了,只是分开两部分来写还是有点那啥。对于强迫症患者来讲,还可以使用动态原型法:
Js代码
![](http://pigkiller.iteye.com/images/icon_star.png)
var MathUtil = function(version, programmer) {
this.name = name;
this.programmer = programmer;
// 使用必要条件进行检测,然后添加函数。
if(typeof this.add != "function") {
// 缓存MathUtil.prototye
var proto = MathUtil.prototye;
// 加法
proto.add = function(aaa, bbb) {
var result = aaa + bbb;
alert("result == " + result);
};
// 减法
proto.reduce = function(aaa, bbb) {
var result = aaa - bbb;
alert("result == " + result);
};
// 乘法
proto.multiply = function(aaa, bbb) {
var result= aaa * bbb;
alert("result == " + result);
};
// 除法
proto.divide = function(aaa, bbb) {
var result= aaa / bbb;
alert("result == " + result);
};
}
};
以上对prototype新增方法的代码在使用new操作符执行时,只会进入判断一次,然后为MathUtil.prototype追加了相应的函数方法。
是否要将prototype放在和构造函数平级还是放在构造函数体内,都没有错,就看个人或者团队喜好,不过最好统一才行。
最后再次强调我们刚才碰到的2个坑:
1.当为MathUtil的prototype追加函数时,如果使用了MathUtil.prototype = {...};那么已经将MathUtil.prototype指向的对象重新定位了,这个时候constructor指向了Object,需要手动指回到MathUtil。最为保险的做法是MathUtil.prototype.add = function() {...};这样的方式来添加,这种方法没有替换MathUtil.prototype指向的实例,所以不会产生不可预料的问题。
2.当MathUtil的属性是数组时,绝对不能将其定义在prototype里面,不然会有属性值覆盖问题。
这个应该是一个必然。因为需要跨时间、空间不同开发人员的协作,代码的重用。具体也就不多说了。
js开发小白一般怎么开发程序?我记得我刚入行是这么写的:
Js代码
![](http://pigkiller.iteye.com/images/icon_star.png)
var a = 1;
var b = 2;
function add(aaa, bbb) {
var result= aaa + bbb;
alert("result == " + result);
}
add(a,b);
add函数很简单,就是计算传入两个数字之和然后alert结果。需求到了后来陆陆续续加上了减法、乘法、除法,我也对应增加了reduce、multiply、divide方法。
所以我的代码变成了以下这个样子:
Js代码
![](http://pigkiller.iteye.com/images/icon_star.png)
var a = 1;
var b = 2;
// 加法
function add(aaa, bbb) {
var result= aaa + bbb;
alert("result == " + result);
}
// 减法
function reduce(aaa, bbb) {
var result= aaa - bbb;
alert("result == " + result);
}
// 乘法
function multiply(aaa, bbb) {
var result= aaa * bbb;
alert("result == " + result);
}
// 除法
function divide(aaa, bbb) {
var result = aaa / bbb;
alert("result == " + result);
}
// 执行加、减、乘、除
add(a, b);
reduce(a, b);
multiply(a, b);
divide(a, b);
突然有一天,小伙伴说哥,你这几个函数我们项目经常用到,可不可以提供出来让我们调用?我说这个简单。于是我把加减乘除的函数单独放置到了一个mathUtil.js文件中,这个文件的内容如下:
Js代码
![](http://pigkiller.iteye.com/images/icon_star.png)
// 加法
function add(aaa, bbb) {
var result= aaa + bbb;
alert("result == " + result);
}
// 减法
function reduce(aaa, bbb) {
var result= aaa - bbb;
alert("result == " + result);
}
// 乘法
function multiply(aaa, bbb) {
var result= aaa * bbb;
alert("result == " + result);
}
// 除法
function divide(aaa, bbb) {
var result = aaa / bbb;
alert("result == " + result);
}
这个时候其实就是进入了最最原始的插件开发了。因为我写的这份代码被跨时间、跨空间供不同开发人员协作使用,这份代码也做了重用,减少了重复劳动。
接下来就是完善插件的过程了。
优化:方法直接暴露在全局作用域,容易命名冲突且通过作用域查找性能消耗大。没有面向对象编程,纯程式化的函数罗列。解决方案:使用对象封装。
对于JavaScript的面向对象的设计使用,这个也是难点,必须坐下来好好说说。
javascript对象的生成方法有2种:
Js代码
![](http://pigkiller.iteye.com/images/icon_star.png)
// 字面量定义
var person1 = {
name: "peter",
age: 18,
sayHello: function() {
alert("hello! I am " + this.name);
}
};
// 创建Object的一个实例
var person2 = new Object();
person2.name = "william";
person2.age = 19;
person2.sayHello = function() {
alert("hello! I am " + this.name);
};
以上虽然能创建对象,但是有个缺点。如果要创建多个对象,就需要重复写以上的代码。为了解决这个问题我们可以使用:
工厂模式:
Js代码
![](http://pigkiller.iteye.com/images/icon_star.png)
// 工厂模式
function createPerson(name, age) {
var o = new Object();
o.name = name;
o.age = age;
o.sayHello = function() {
alert("hello! I am " + this.name);
};
return o;
}
var person1 = createPerson("peter", 18);
var person2 = createPerson("william", 19);
工厂模式已经可以满足一般我们的开发需要了,但是这个也是有点问题。命名不够直接,实现方面也可以简化。怎么弄?使用构造函数模式:
Js代码
![](http://pigkiller.iteye.com/images/icon_star.png)
// 构造函数模式
var Person = function(name, age) {
this.name = name;
this.age = age;
this.sayHello = function() {
alert("hello! I am " + this.name);
}
};
var person1 = new Person("peter", 18);
var person2 = new Person("william", 19);
从工厂模式跨越到了构造模式,跨度有点大,这里解释一下:
相比较工厂模式,构造函数模式有以下不同:
A.没有显式创建对象
B.直接将属性、方法赋予了this对象
C.没有return
这些都是因为在使用new 操作符构造函数模式时经历以下过程:
A.创建一个对象
B.将构造函数的作用域赋给新对象,所以this就指向了这个新对象
C.执行构造函数中的代码,例子中就是赋予新对象属性和方法
D.返回新对象
虽然构造函数模式隐含省略了很多步骤且不怎么好理解。但是使用起来却是简单直接。例如我要创建一个person类,new Person()就得到了(和java的语法简直一模一样啊~32个赞!)。但是要是使用工厂模式,就必须调用createPerson();有时候工厂模式的函数是别的人写的,写成了createHuman,这不逼死强迫症嘛?!
另外一个重要的好处是:使用构造函数模式产生的对象是该函数的实例。怎么讲呢?如果使用工厂模式,得到的person只是Object的实例。而构造函数模式得到的person却是更为具体的Person的实例!当然它同时也是Object的实例。
这个优点在使用instanceof操作符进行实例判断时可以给出我们准确的判断,如果都是工厂模式出来的产品,那么检测结果就是大家都是Object的实例。
在这里,如果不考虑构造函数模式的一些细节问题。这种插件的写法已经可以应用到我们的项目当中了,不知道你们有没有在项目中见到其他人是这么写的?所以我们的mathUtil.js文件就可以写成下面这种样子了:
Js代码
![](http://pigkiller.iteye.com/images/icon_star.png)
function MathUtil() {
// 加法
this.add = function(aaa, bbb) {
var result= aaa + bbb;
alert("result == " + result);
};
// 减法
this.reduce = function(aaa, bbb) {
var result= aaa - bbb;
alert("result == " + result);
};
// 乘法
this.multiply = function(aaa, bbb) {
var result= aaa * bbb;
alert("result == " + result);
};
// 除法
this.divide = function(aaa, bbb) {
var result = aaa / bbb;
alert("result == " + result);
};
}
使用方法:
Js代码
![](http://pigkiller.iteye.com/images/icon_star.png)
// 引用mathUtil.js文件后使用方式:
var mathUtil1 = new MathUtil();
mathUtil1.add(1, 2);
这样以来插件就实现了面向对象的抽象过程,且将插件需要的各种变量封装了起来。
以上的构造函数模式还是有点小问题的,对于一个对技术精益求精的前端开发,这点也是不能容忍的。问题在于mathUtil函数体重的add等方法都是对象(函数也是特殊对象,定义一个函数就相当于实例化了一个对象了)。当new一个MathUtil的实例时,实例中的方法都是一样的,但是重复了。其实这个是没有必要的。怎么办?
最简单粗暴的方式就是把相关的函数提取出来(为了表述方便加入version变量):
Js代码
![](http://pigkiller.iteye.com/images/icon_star.png)
function MathUtil() {
// 版本号
var version = "1.0";
// 加法
this.add = add;
// 减法
this.reduce = reduce;
// 乘法
this.multiply = multiply;
// 除法
this.divide = divide;
}
// 加法
var add = function(aaa, bbb) {
var result= aaa + bbb;
alert("result == " + result);
};
// 减法
var reduce = function(aaa, bbb) {
var result= aaa - bbb;
alert("result == " + result);
};
// 乘法
var multiply = function(aaa, bbb) {
var result= aaa * bbb;
alert("result == " + result);
};
// 除法
var divide = function(aaa, bbb) {
var result = aaa / bbb;
alert("result == " + result);
};
以上的改造后,如果new多个MathUtil的实例时,add函数只有一个实例,那就是指向了和MathUtil平级的那个add函数。其他函数相同情况。
但是从实际操作来讲,还不如消耗一点性能,不将插件的函数提取出来。因为这样一来暴露出来的变量急剧增加,很不好控制。
有没有方案解决这种问题呢?即多个实例的共同方法、对象指向一个,复用方法。答案就是原型模式:
Js代码
![](http://pigkiller.iteye.com/images/icon_star.png)
var MathUtil = function() {};
MathUtil.prototype = {
// 将构造函数置为MathUtil,这里一定要将constructor重新设置回MathUtil,不然会指向Object的构造函数
constructor: MathUtil,
// 版本号
version: "1.0",
// 加法
add: function(aaa, bbb) {
var result= aaa + bbb;
alert("result == " + result);
},
// 减法
reduce: function(aaa, bbb) {
var result= aaa - bbb;
alert("result == " + result);
},
// 乘法
multiply: function(aaa, bbb) {
var result= aaa * bbb;
alert("result == " + result);
},
// 除法
divide: function(aaa, bbb) {
var result = aaa / bbb;
alert("result == " + result);
}
};
以上的原型模式看起来已经比较完美了,但是还是有两个比较突出的问题:
A.无初始化变量入口
B.当属性为Array类型时,会发生属性篡改
对于MathUtil这个函数,无初始化变量入口的意思是在new出一个实例时想直接将version传入,覆盖默认值。但是,以上的设计明显是做不到的。
再说属性篡改问题,为了说明这个问题我们在mathUtil对象中加入一个programmer变量,用来存储开发人员的姓名。
Js代码
![](http://pigkiller.iteye.com/images/icon_star.png)
var MathUtil = function() {};
MathUtil.prototype = {
//省略了其他的代码
//开发人员
programmer: []
};
Js代码
![](http://pigkiller.iteye.com/images/icon_star.png)
// 实例化一个MathUtil,并给programmer里增加一个开发人员姓名
var m1 = new MathUtil();
m1.programmer.push("william");
// 实例化一个MathUtil,没有对programmer进行任何操作的情况下,m2的programmer属性无缘无故就多出来一个"william"
var m2 = new MathUtil();
m2.programmer;
这是由于m1、m2共享了同一个原型对象导致的,而Array属于引用类型,所以就造成了m1的programmer其实和m2的programmer是同一个实例的情况。所以呢,我们就人为地对对象的属性做个分类,如果是函数,我们就统一放到prototype属性指向的实例当中,如果只是非引用类型或者Array类型的属性我们放在构造函数里面。而且我们同时改造构造函数接受参数:
Js代码
![](http://pigkiller.iteye.com/images/icon_star.png)
var MathUtil = function(version, programmer) {
this.name = name;
this.programmer = programmer;
};
MathUtil.prototye = {
// 将构造函数置为MathUtil,这里一定要将constructor重新设置回MathUtil,不然会指向Object的构造函数
constructor: MathUtil,
// 加法
add: function(aaa, bbb) {
var result= aaa + bbb;
alert("result == " + result);
},
// 减法
reduce: function(aaa, bbb) {
var result= aaa - bbb;
alert("result == " + result);
},
// 乘法
multiply: function(aaa, bbb) {
var result= aaa * bbb;
alert("result == " + result);
},
// 除法
divide: function(aaa, bbb) {
var result = aaa / bbb;
alert("result == " + result);
}
};
调用测试的代码:
Js代码
![](http://pigkiller.iteye.com/images/icon_star.png)
// 引用mathUtil.js文件后使用方式:
var m1 = new MathUtil("william",["william"]);
m1.programmer.push("william2");
var m2 = new MathUtil("peter",["peter"]);
m1.programmer.push("peter2");
这个时候m1,m2各自的programmer对应的就是不同数组了。而且还同时具有初始化参数的能力。
以上的写法已经比较完美了,只是分开两部分来写还是有点那啥。对于强迫症患者来讲,还可以使用动态原型法:
Js代码
![](http://pigkiller.iteye.com/images/icon_star.png)
var MathUtil = function(version, programmer) {
this.name = name;
this.programmer = programmer;
// 使用必要条件进行检测,然后添加函数。
if(typeof this.add != "function") {
// 缓存MathUtil.prototye
var proto = MathUtil.prototye;
// 加法
proto.add = function(aaa, bbb) {
var result = aaa + bbb;
alert("result == " + result);
};
// 减法
proto.reduce = function(aaa, bbb) {
var result = aaa - bbb;
alert("result == " + result);
};
// 乘法
proto.multiply = function(aaa, bbb) {
var result= aaa * bbb;
alert("result == " + result);
};
// 除法
proto.divide = function(aaa, bbb) {
var result= aaa / bbb;
alert("result == " + result);
};
}
};
以上对prototype新增方法的代码在使用new操作符执行时,只会进入判断一次,然后为MathUtil.prototype追加了相应的函数方法。
是否要将prototype放在和构造函数平级还是放在构造函数体内,都没有错,就看个人或者团队喜好,不过最好统一才行。
最后再次强调我们刚才碰到的2个坑:
1.当为MathUtil的prototype追加函数时,如果使用了MathUtil.prototype = {...};那么已经将MathUtil.prototype指向的对象重新定位了,这个时候constructor指向了Object,需要手动指回到MathUtil。最为保险的做法是MathUtil.prototype.add = function() {...};这样的方式来添加,这种方法没有替换MathUtil.prototype指向的实例,所以不会产生不可预料的问题。
2.当MathUtil的属性是数组时,绝对不能将其定义在prototype里面,不然会有属性值覆盖问题。
相关文章推荐
- phonegap中java插件开发及javascript(js)调用java代码
- 超全超实用的Javascript类库和jQuery插件大全之二:文字处理,表格和列表处理,实用的javascript开发工具
- jQuery相当于对 javascript二次开发,所以基于 jQuery实现的各种插件直接调用即可
- 初探 利用 javascript 开发 Chrome 浏览器插件
- JavaScript之三:jQuery插件开发(一)
- [JavaScript] Firefox 插件开发(网站编辑转发工具)
- JavaScript之jQuery-9 jQuery 开发插件(添加新全局函数、添加jQuery对象方法、添加新简写方法、方法参数)
- 使用JavaScript开发IE浏览器本地插件实例
- (转)javaScript插件开发
- javascript插件开发的一些感想和心得
- 超全超实用的Javascript类库和jQuery插件大全之二:文字处理,表格和列表处理,实用的javascript开发工具
- 关于javaScript开发工具的问题(我在myeclipse里安装aptana插件过程)
- 超全超实用的Javascript类库和jQuery插件大全之二:文字处理,表格和列表处理,实用的javascript开发工具
- 使用JavaScript开发IE浏览器本地插件实例
- Vim下的Web开发之html,CSS,javascript插件
- jquery插件开发导读
- Android开发中java与javascript交互:PhoneGap插件vs addJavascriptInterface
- eclipse 或myeclipse中安装插件spket (用于javascript开发) ----- 安装与使用详细
- JavaScript的jQuery库插件的简要开发指南
- javascript插件开发的一些感想和心得