《javascript实战》Part1——2成功javascript开发者的7个习惯

一、更多面向对象的javascript

1)简单创建对象

var newObject = new Object();
//变量newObject指向一个Object实例,Object是javascript所有对象的基类。
可以在任何时候给对象添加属性和方法

newObject.firstName = "frank";

newObject.sayName = function(){
  alert(this.firstName);
}

调用对象的方法:newOjbect.sayName();
与大多成熟的面向对象语言不同的是——不必为一个对象实例创建类或者蓝图!
如上面所写,在运行时创建它;可以随时给对象添加属性和方法!
本质:javascript把所有对象当做关联数组,使用点分隔表示法。

可以这样使用:
var theFirstName = newObject["fitstName"];
newObject["sayName"]();

若你想基于某种逻辑调用某个对象的方法——

var whatFunction ;
if(whatVolume == 1){
  whatFunction = "sayName";
}else if(whatVolume == 2){
  whatFunction = "sayLoudly";
};
newObject[whatFunction]();

可以向一个对象添加一个已经存在的函数:

function sayLoudly(){
  alert(this.firstName.toUpperCase());
}
newObject.sayLoudly = sayLoudly;

注意this关键字的使用法:它指向的对象将会在运行时动态计算。上面的this指向的是函数sayLoudly()作为其成员的那个类——即Object。即如果sayLoudly是另外一个对象的一部分,this就会引用另一个对象。即运行时绑定!它允许代码的共享,本质上是一种继承。

2)使用JSON创建对象

JSON——Javascript对象表示法。是javascript规范中的一个核心部分。最初目的是为了快速简便地定义复杂的对象关系图,即嵌套于其他对象中的对象实例。
JSON可运转的因素:javascript对象只是隐藏在面具下的关联数组。
用JSON创建刚才的newObject:

function sayLoudly(){
    return this.firstName.toUpperCase();
}
var newObject = {
     firstName : "frank",
     sayName : function(){alert this.firstName;},
     sayLoudly : sayLoudly,
  lastName : {
           lastName : "Zammetti" ,
           sayName : function(){alert(this.lastName);}
    }
};
newObject.lastName.sayName();

 注意:
(1)函数可以是内联的也可以引用外部函数;
(2)第一个say是对象的一个成员,这里是方法;第二个是对一个已经存在的对象的引用;
(3)JSON中可以随意地嵌套对象定义来创建对象的层级关系

3)类的定义

所有的东西都是对象(只有一小部分例外,如一些内置的原语)函数本身就是对象。

每次创建对象的一个新实例都从零开始,更好的方法是——创建一个类!
类就是一个函数,这个函数同样被当做类的构造函数来提供服务
重新把newObject 写成一个类,重新命名为newClass:

function newClass(){
     this.firstName = "frank";
     this.sayName = function(){
        alert(this.firstName);
    }
} 
var nc = new newClass();
nc.sayName();       

创建多少个newClass的实例就创建多少,它们含有同样的属性和方法,同样的属性初始值
缺点:newClass的每个实例都含有类里面的属性和方法的副本,占用了更多的内存。
改进:所有的实例可以共享相同的sayName()副本的话,可以节省内存。(适合更多代码的情况下)。具体见下面的方法

4)原型

javascript中每一个独立的对象都有一个与之关联的原型(prototype)属性。
其他语言没有完全与prototype相等的东西;prototype可以看做一个简化的继承形式;

其工作方式:当你构造一个对象的新实例时,定义在对象的原型中的所有属性和方法,在运行时都会附着在哪个新的实例上

例子:

function newClass(){
    this.firstName = "frank";
}
newClass.prototype.sayName = function(){
    alert(this.firstName);
}
var nc = new newClass();
nc.sayName();

优点:无论创建多少个实例,在内存中sayName()函数只会有一个单独的实例。这个方法实际上市附加在每个实例上,而且this关键字仍然是在运行时被计算的。this通常指向它所属的那个特定的newClass实例。比如有两个newClass的实例分别叫做nc1和nc2,nc1.sayName()的调用将this指向nc1,对nc2.sayName()的调用将this指向nc2.

5)四种方法的比较:

一些准则:
a)创建一个非常大的类,可能会有复杂的实例——一定是原型方法(带来最好的内存使用效率)
b)创建一个单独的类,且这个类将只有一个实例,推荐定义一个类(使逻辑化最强、最类似于更全面的面向对象语言的,易于项目新开发人员理解)
c)① 对象层级关系嵌套层次很多
    ② 需要在一个动态方式中定义一个对象(一段逻辑代码的输出结果)
    ③ 需要将对象序列化并且通过网络进行传输

    ④ 需要重构一个从服务器传送来的对象时
     以上一定首选JSON

6)面向对象的好处

a)每一个对象本质上就是一个命名空间(以此来模拟java和c#的包)
b)使用对象来隐藏数据。例如

function newClass(){
    this.firstName = "frank";
    lastName = "Zammetti";
}
var nc = new newClass();
alert(nc.firstName);  //弹出警告
alert(nc.lastName); //undefined

注意定义字段的不同:(对于方法也适用)
①任何使用this关键字定义的字段,都可以在类之外访问;
②任何没有使用this定义的字段,都只能在类的内部访问;

c)javascript的内置对象可以通过使用它们的原型来扩展(扩展内置对象要谨慎)
d)可以从其他的对象中“借”函数,并把它们添加到自己的对象中。例如:
通过输出newClass本身来显示newClass的firstName字段——实现一个toString()函数;
还要在它上面使用String对象中的toUpperCase()函数

function newClass(){
    this.firstName = "frank";
    this.changeUpper = String.toUpperCase;
    this.toString = function(){
        alert(this.changeUpper(this.firstName));
    }
}
var nc = new newClass();
alert(nc);

注意思想:调用了toString()函数,但不是作为String对象的一个方法。而是通过名为changeUpper()的newClass的属性指向String对象toUpperCase()方法的一个引用调用的。
好处是:当创建一个对象后又想创建一个新的,要使用原来的代码,只需引用其他类里的已存在的方法即可。

二、柔性衰减和不唐突的javascript

不唐突的javascript基本原则:
(1)保持javascript独立;(作者不完全同意)
(2)通常允许柔性衰减;
(3)从不使用浏览器嗅探脚本来判断一个浏览器的能力;(而是去检查对象的存在和对象的能力。一个好的习惯是在访问一个给定对象之前检查它是否存在)
(4)任何情况都不写浏览器不兼容的代码;
(5)合适的作用域变量;
对于变量,除了真正具有全局意义的,都应该定义成局部变量;
尤其在使用Ajax时,异步时,全局变量可能会引起许多难以调试的问题。一个糟糕例子:

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8" />
    <title>糟糕的变量的例子</title>
    <script>
        var fauxConstant = "123";
        function badFunction(){
            fauxConstant = "456";
        }
        function goodFunction(){
            var fauxConstant = "456"  //与外部的全局变量不是一个东西。作为局部变量,外部无法访问
        }
        function test(){
            alert(fauxConstant); //输出“123”
            badFunction();
            alert(fauxConstant);
            goodFunction(fauxConstant);
            alert(fauxConstant);
        }
    </script>
</head>
<body>
    <input type="button" onclick="test()"; value="click me!" />
</body>
</html>

任何生命在函数内部、没有使用关键字var的变量,都将在这个函数外部存在
(6)对于可访问性,避免用鼠标事件触发的触发器(改成键盘事件)

三、不只是为了秀:关注可访问性

四、错误处理
类似于java和C#,自定义一个错误处理函数。
关于错误和异常:
错误——是一个条件,并不预期其发生,通常会导致程序崩溃(最好生成一个错误提示信息说程序无法继续)
异常——是一个状态。预期可能发生,程序应该能够以某种方法处理并继续运行。
错误实际上是一个伪装的异常,若做合理计划可以像处理其他异常一样处理——使代码更健壮

五、调试机制

六、浏览器扩展
firefox——1、venkman   2、FIrebug   3、Page Info  4、Web Developer
IE——1、httpwatch  2、Web Accessibility工具条   3、 IEDocMon 等等

七、 javascript库



posted @ 2013-08-06 17:15  果粒遇到前端  阅读(154)  评论(0编辑  收藏  举报