Web开发时,我们可能经常抱怨,javascript。它太耗时间精力,甚至让我们觉得它恶心。服务器端,我们有优秀的java语言和webwork、spring等框架来帮助我们提高效率。而客户端只有灵活、难以掌握的javascript,那么我们的希望在哪呢?但愿下面的内容能够对你有些帮助。
1、它是怎样的?
Javascript目前由二块构成:Core(核心部分)+DOM实现部分。(DOM是w3c定义的针对HTML、XML文档编程的一系列接口。通过这些接口,我们可以改变文档结点的结构、样式、内容。实现这些接口的语言可以是java、Python,javascript等。)
|
Core |
定义了语法规则,及内置的全局对象(Date、Function等),全局方法(parseFloat),全局属性(NaN,undefined等) |
|
Dom |
针对HTML文档与XML文档操作的API |
2、 慢在哪?
2.1、java VS javascript
Java是面向对象的代表性语言之一,面向对象语言是时下比较流行、开发效率高的主流开发语言。面向对象语言包括几个主要特性:抽象,继承,封装和多态。Javascript本质上不是面向对象的,而是基于对象的。基于对象的语言对上面四个特性支持很差,或者只支持部分特性。
|
|
抽象 |
继承 |
多态 |
封装 |
|
java |
具备:类,接口,抽象类四个概念 |
支持:
通过关键字
Extends,implements实现 |
支持:
1)表现在对象的方法可以重载
2)子类可以被当作父类处理 |
支持:
private,
friendly,
protected,
public
四个级别的封装 |
|
javascript |
仅具备:
类,这一个概念 |
支持很差:
通过prototype实现;
Function的apply或call方法间接实现。 |
不支持 |
支持很差:仅支持private,
public二个级别 |
|
比较结果 |
1恶劣的继承导致:无法实现子类与父类之间关系的判断,并且子类无法转化成父类。所以无法根据类的类型处理业务:处理父类的代码,无法处理子类。——扩展性差
2 陈旧的代码书写方式导致:本不好的封装性变的更加差劲。这样对象间的隔离成本增加,内聚性弱。 |
|
大大降低了开发效率 |
2.2、浏览器的兼容性
Core与Dom部分都存在着浏览器平台的差异性,进一步降低了开发的效率。
3、 开始加速
3.1、加强封装性
提倡的写法
- function A(){
- var locate1 = "1oh";
- this.locate2 = "2oh";
- var method1 = function(){
- alert(locate1);
- }
- this.method2 = function(){
- alert(this.locate2);
- method1();
- }
- }
A对象的locate1与method1是private级别的; locate2与method2是public级别的。
优点:封装性好,实现代码变化的隔离。
缺点:代码可读性差。
弥补方式:利用javascript的优秀插件,如:jseclipse。
禁止的写法
- function A(){
- var locate1 = "1oh";
- var method1= function(){
- alert(locate1);
- };
- }
- A.prototype={
- locate2:"2oh",
- method2:function(){
- alert(this.locate2);
- },
- method3:function(){
- alert(locate1);
- method1();
- }
- }
- var a = new A();
- a.method2();
- a.method3();
优点:代码可读性好。
缺点:
|
没有全局的私有变量 |
如果执行a.method3();根本无法访问变量locate1。 |
|
prototype中的方法是公共的。 |
a.method2()成功访问,在prototype中定义的方法是public级别;无法在prototype中定义全局的private变量。 |
|
总体效果 |
1) 封装性极其差
2) 代码调用不方便。 |
3.2 类继承
禁止写法
|
prototype继承 |
万恶之首:目前有很多继承写法,都是直接或者间接使用它。严重破坏封装性。 |
|
没法实现多态:只是简单的复用,这种继承意义不大。 |
|
apply,或者call |
只是复用:简单的在当前对象中,执行对象之外的另一个方法。 |
这几种javascript的继承写法虽然目前被大量的使用,但是他们的缺点是明显的,因此我们不建议采用这些常见的javascript继承写法。
推荐写法
例子很长,先给大家一些看完的动力吧,下面是它的优点。
|
代码复用 |
如果A继承B,那么A可复用B中public级别的资源 |
|
单一,多层的继承 |
B可以继承C,A可以继承B,不存在A继承B又继承C。 |
|
多态 |
A是父类,B与C是A的子类,如果存在一个方法X,是处理A类的,那么它也能处理B与C类。扩展性好,容纳了变化:可以处理,将来因业务需求新建的D类。 |
例子:
【注意事项】:
1) 需要用这种继承的写法,请将下面的方法当作javascript 的api,不要覆盖。
|
方法名称 |
方法作用 |
参数说明 |
|
getClassName |
获得对象的名称。 |
无 |
|
inherit |
实现对象之间的单一多层的继承 |
1:被继承的父类名,非字符串
2:父类初始化需要的参数 |
|
father |
如果子类覆盖了父类的某个方法,用它来回调父类的这个方法 |
1:回调的方法名称,字符串格式
2:回调方法需要的参数 |
|
typeOf |
判断子类的类型,与typeof是不一样的。 |
类的名称,非字符串形式。 |
|
toParent |
将子类转换成父类 |
父类的名字,非字符串形式。 |
2) 在子类的
第一行执行继承。如果要覆盖父类的某个方法,并且要用父类的这个方法,那么请在子类的方法中回调父类的那个方法。
3.3、活用闭包
所谓闭包,通俗的讲,使用函数的范围,已经不在函数的定义范围。
优点:进一步提高代码的封装性。
缺点:ie6的垃圾收集机制存在着bug,当进行ui编码时会出现一些问题。
闭包的特点
1、作为一个函数变量的一个引用 - 当函数返回时,其处于激活状态。
2、一个闭包就是当一个函数返回时,一个没有释放资源的栈区。
闭包的写法
- function A(){
- var answer1 = function(str){
- alert("这里提供复杂功能1");
- }
- var answer2 = function(str){
- alert("这里提供复杂功能2");
- }
- this.getAnswer = function(flag){
- if(flag)
- return answer1;
- else
- return answer2;
- }
- }
-
- var control = new A();
- var a1 = control.getAnswer(true);
- var a2 = control.getAnswer(false);
- a1();
- a2();
-
-
-
-
-
- function A(){
- var answer1 = function(str){
- alert("这里提供复杂功能1");
- }
- var answer2 = function(str){
- alert("这里提供复杂功能2");
- }
- this.getAnswer = function(flag){
- if(flag)
- return answer1;
- else
- return answer2;
- }
- this.answer = function(){
- answer1();
- }
- }
-
- var control = new A();
- var a1 = control.getAnswer(true);
- a1();
- a1 = "1";
- control.answer();
3.4、函数式编程
它的基本特点是:将函数(或对象)赋值给一个变量。前面我们已经采用了这种写法。
优点:代码可读性好。适合web页ui方面的开发
错误的写法
- function A(){
- alert(B());
- var B = function(){
- return "ok";
- }
- }
- A();
正确的写法
- function A(){
- var B = function(){
- return "ok";
- }
- alert(B());
- }
- A();
附:javascript是非常灵活的:
1)基于对象的:有对象与类的概念,也有独立于对象的函数概念
2)解释型:请把握住运行时与时间轴这个概念:它能自动转化变量的类型与这个特点紧密相连;一段代码是当作函数,还是一个类,也与这个有关。
2)弱类型:会将变量自动转化为当前合适的类型或者基本数据类型,这个特点基于它是解释型的语言。
这些充分体现了javascript的灵活型。建议使用它,不要走极端:将其对象的一面在需要的时候充分运用,但没有必要任何情况下都这样做。所谓灵活:在不同的情况,可以有适合的方式可用。
(完)