JavaScript学习小结(二)

  • 关于JavaScript的版本

    目前Js标准有两个支撑,分别为ECMA-262和ECMA-357.357是针对262的一个XML扩展。

  • 关于JavaScript的运行环境

    只要有解释器,客户端/服务器端均可。由于浏览器默认装载了解释器,所以通过浏览器学习Js是很方便的。

  • 关于JavaScript的类型变换

基本数据类型之间,对象和基本数据类型是可以自动转换的。

基本数据类型->对象的转换,涉及到一个概念--瞬态对象。所谓的瞬态,是指被系统临时创建用后就丢弃的。

如下代码即为瞬态对象的典型例子。

1 var s = 'abc';
2 console.log(s.length);
var s = 'abc';
console.log(s.length);

至于对象->基本数据类型的转换,则可能涉及到对象的toString,valueOf方法。

  • 关于传值和传址

基本数据类型:传值

函数和数组:传址。关于这一点还是和传统Java有区别的,JavaScript中更像是引用的传值。以下的代码较好地解释了这一点。

 1 // This is another version of the add_to_totals() function. It doesn't
 2 // work, though, because instead of changing the array itself, it tries to
 3 // change the reference to the array.
 4 function add_to_totals2(totals, x)
 5 {
 6     newtotals = new Array(3);
 7     newtotals[0] = totals[0] + x;
 8     newtotals[1] = totals[1] + x;
 9     newtotals[2] = totals[2] + x;
10     totals = newtotals;  // This line has no effect outside of the function
11 }

 

字符串:比较特殊,可以认为是传值。这一点和Java不同,值得注意。

  • 关于变量的重复声明

对变量没有任何影响。

 

  • 关于未定义的变量

未声明的变量不能直接读,否则会发生错误;但却可以直接赋值,赋值的过程中系统隐式声明它。

 

  • 关于变量的作用域

全局变量就是全局对象的属性,局部变量就是调用对象的属性。调用对象和全局对象共同构成了作用域链(Scope chain)。变量名解析(variable name resolution)就是在这个作用域链中查询变量的过程。按照我的理解,局部变量所在的调用对象实际上和函数相关,它是指函数被调用时创建的。该调用对象的一个属性被初始化成一个名叫 arguments 的属性,它引用了这个函数的 Arguments 对象--函数的实际参数。所有用 var 语句声明的本地变量也被定义在这个调用对象里。这个时候,调用对象处在作用域链的头部,本地变量、函数形式参数和 Arguments 对象全部都在这个函数的范围里了。其实,由于JavaScript是通过词法来划分作用域的,当一个函数在定义的时候,其作用域链就形成了,并成为该函数的内部状态。只不过当调用的时候,所创建的调用对象被添加到定义时创建的作用域链的头部。

  • 关于闭包

代码和作用域的综合体叫做闭包。所有的JavaScript函数都是闭包。

只有当一个嵌套函数被到处到它所定义的作用域外时,这种闭包才是有趣的。--摘自犀牛书

 

  •  关于类,构造函数和原型

 JavaScript还不支持真正的类,其所为的类为伪类(pseudoclass)。构造函数和原型是伪类理论的重要支撑工具。

一个对象的创建分为两步,第一步为new ,创建一个新对形象;第二步,新对象调用构造函数,并根据构造函数设置属性(方法可以看做函数属性)。比较特殊的是,所有的构造函数均有一个特殊的属性-prototype,该属性在函数被定义时就已经初始化为原型对象了。默认的,改原型对象有一个constructor属性,其值恰好为构造函数。添加给原型对象的任何属性,都会成为构造函数所初始化的对象的属性(通过属性值的查找完成继承)。

 

  • 关于类的继承

(1)子类的构造函数的原型对象=父类的实例

(2)子类的构造函数=子类的构造函数

(3)删除父类构造函数所创建的属性。(不必要,重复的)

 

示例代码:

 1 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
 2         "http://www.w3.org/TR/html4/loose.dtd">
 3 <html>
 4 <head>
 5     <title></title>
 6     <script src="myJs.js" type="text/javascript"></script>
 7 </head>
 8 <body>
 9 <!--
10 <a href="javascript:void f(5);"> Open new window </a>
11 -->
12 <input type="button" onClick="javascript:var f = new outer(1); alert(f.inner1(2));">闭包1</input>
13 <br>
14 <input type="button" onClick="javascript:var f = new outer(2); f.x=1000; alert(f.inner2(3));">闭包2</input>
15 <br>
16 <input type="button" onClick="javascript:myClosure.x=1; alert(myClosure.x); var f = myClosure(1000); alert(f()); alert(f()); alert(f()); alert(f());">作用域与闭包</input>
17 <br>
18 <input type="button" onClick="javascript:var obj = {}; makeProperty(obj, 'Xxx'); obj.setXxx(100);alert(obj.getXxx());">闭包之保护变量避免外部访问</input>
19 <br>
20 <input type="button" onClick="javascript:var obj = {}; makeProperty2(obj, 'Xxx'); obj.setXxx(100);alert(obj.getXxx());">闭包之重名变量2</input>
21 <br>
22 <input type="button" onClick="javascript:var f = myClosure2(10); alert(f()); alert(f()); alert(f()); alert(f());">闭包里的this</input>
23 <br>
24 <input type="button" onClick="javascript:var f = new outer(2); f.x=1000; alert(outer.prototype.constructor);">构造函数的prototype.constructor</input>
25 <br>
26 <input type="button" onClick="javascript:var f = new outer(2); f.x=1000; alert(outer.prototype.prototype);">构造函数的prototype的prototype</input>
27 <br>
28 <input type="button" onClick="javascript:var f = new outer(2); f.x=1000; alert(f.prototype);">对象的prototype</input>
29 <br>
30 <input type="button" onClick="javascript:var f = new outer(2); f.x=1000; alert(f.constructor);">对象的constructor</input>
31 <br>
32 <input type="button" onClick="javascript:var f = new outer(2); f.x=1000; alert(f.inner1.prototype.constructor);">对象的方法prototype.constructor2</input>
33 <br>
34 <input type="button" onClick="javascript:alert(makefunc.prototype.constructor);">普通函数的prototype.constructor</input>
35 <br>
36 <input type="button" onClick="javascript:var f = makefunc(1); alert(f.prototype.constructor);">普通函数的prototype.constructor2</input>
37 </body>
38 </html>


JavaScript

  1 /**
  2  * Created with JetBrains WebStorm.
  3  * User: hehe
  4  * Date: 13-2-1
  5  * Time: 上午10:48
  6  * To change this template use File | Settings | File Templates.
  7  */
  8 
  9 var abc = 1000;
 10 /*
 11 document.body.onload=function(){
 12     document.write('this is a test<br>');
 13     document.write(new Boolean());
 14     }
 15 */
 16 
 17 function f(x){
 18     //print(x);
 19     console.log(x);
 20     arguments[0] = null;
 21     //print(x);
 22     console.log(x);
 23     }
 24 
 25 /*
 26 alert(
 27 function(x){
 28     if(x<=1) return 1;
 29     return x * arguments.callee(x-1)
 30     }(5));
 31 */
 32 
 33 var calculator = {
 34     operand1:1,
 35     operand2:1,
 36     computer:function(){
 37     this.result=this.operand1+this.operand2;
 38     }
 39 };
 40 
 41 calculator.computer();
 42 console.log(calculator.result);
 43 
 44 function makefunc(x){
 45     return function(){return x;}
 46 }
 47 
 48 function outer(x){
 49     this.x = x;
 50     }
 51 
 52 outer.prototype.inner1 = function(y){
 53     return this.x + y;
 54     }
 55 
 56 outer.prototype.inner2 = function(z){
 57     return this.x+z;
 58     }
 59 
 60 function myClosure(initVal){
 61     var x=initVal;
 62     return function(){return x++;}
 63 }
 64 
 65 var def = 20;
 66 function myClosure2(initVal){
 67     var x=initVal + this.def;
 68     var abc=1;
 69     return function(){return x++ + this.abc;}
 70 }
 71 
 72 function makeProperty(o, name){
 73     var x;
 74     o["get"+name] = function(){return x;}
 75 o["set"+name] = function(y){x=y;}
 76 }
 77 
 78 function makeProperty2(o, name){
 79     var x;
 80     o["get"+name] = function(){return x;}
 81 o["set"+name] = function(x){x=x;}
 82 }
 83 
 84 function Rectangle(w,h){
 85     this.width = w;
 86     this.height = h;
 87     }
 88 
 89 Rectangle.prototype.area = function(){return this.width*this.height}
 90 
 91 function PositionedRectangle(x,y,w,h){
 92     Rectangle.call(this, w, h);
 93     this.x = x;
 94     this.y = y;
 95     }
 96 
 97 //alert(PositionedRectangle.prototype.constructor);
 98 
 99 PositionedRectangle.prototype = new Rectangle();
100 delete PositionedRectangle.prototyp.width;
101 delete PositionedRectangle.prototyp.height;
102 PositionedRectangle.prototype.constructor = PositionedRectangle
103 PositionedRectangle.prototype.contains = function(x,y){
104     return (x >= this.x && x<= this.x + this.width && y >= this.y && y<= this.y + this.height);
105     }
106 //alert(PositionedRectangle.prototype.constructor);
107 
108 function GenericToString(){}
109 GenericToString().prototype.toString = function(){
110 
111 }

 

  •  关于模块和命名空间

JavaScript本身是不支持模块和命名空间的。

命名空间巧妙地运用了Js对象的属性。

而模块一般多有两种定义方式(其实可以是任意的,只要不把全局命名空间搞乱了就行)。

一种比较优秀的定义模块和命名空间的方法是使用闭包。这有两个好处:一是内部调用可以不用写全称限定名;二是私有的辅助函数或者变量可以很好地隐藏,而只导出公共函数。

另一种为使用类。其实类也是一种特殊的函数-构造函数。

类的初始化方法一般也可分为两种。一为匿名函数定以后的立即调用,即function(){}();另一为构筑一模块的初始化句柄,并把此句柄注册于某个合适的监听器,比如onload。

学以致用,对于JQuery模块来说--JQuery应该算是一个模块了吧,$(JQuery,全局变量命名空间)符号应该是一个对象,$.xxx, $.fn.XXX即可说明。不过从$(selector)来看,$缺又像个函数名,函数在JavaScript里确实本身是一个对象,难道是函数对象?(个人理解哈,不知道对否?欢迎高人指正!)。

 

 

 

posted on 2013-02-07 20:35  hncen  阅读(1050)  评论(0)    收藏  举报

导航