码迷,mamicode.com
首页 > 编程语言 > 详细

javascript高级程序设计

时间:2015-03-18 17:59:17      阅读:217      评论:0      收藏:0      [点我收藏+]

标签:

第一章 Javascript简介

 

一。javascript 是由三个不同部分组成
 
1.核心ECMAscript
2.文档对象模型DOM
3.浏览器对象模型BOM
 
二.ECMAscript大致来说规定下列组成部分
语法
类型
语句
关键字
保留字
操作符
对象
 
历史:ECMAscript开始与web没有依赖关系,web浏览器是ECMA实现可能的宿主环境之一,其他宿主环境还有Node(服务端的javascript实现平台),和Adobe Flash
 
三。文档对象模型DOM
 
四。浏览器对象模型BOM
 
 
 第二章 在HTML中使用Javascript
 
 
一。使用<script>的方法有两种
1.直接页面嵌入
 
包含在<script>的元素会自上而下的依次解释,在解释器对<script>元素内部的代码求值完毕以前,页中的其余内容不会被浏览器显示。
注意,不要再代码上写</script>,否则浏览器认为是结束标志,如
function a(){
alert("</script>");
}
解决办法可以使用转义字符\,如
function a(){
alert("<\/script>");
}
 
2.包含外部javascript
<script type="text/javascript" src="aaa.js"></script>
在解释器对<script>元素内部的代码求值完毕以前,页中的其余内容不会被浏览器显示。
 
如果在XHTML中可以省略</script>,如
<script type="text/javascript" src="aaa.js"/>
 
src元素可以包含来自外部域的javascript,让<script>和<img>元素非常相似,这一点有好处又坏处,在访问不能自己控制的其他服务器上面,假如遇到恶意程序员,改了里面文件的代码。。。
<script type="text/javascript" src="http://www.sdfsdfsdf。com/aaa.js"></script>
注意:无论怎样包含代码,只要不存在defer和async属性,浏览器会根据出现的不同顺序解释,第一个解释完才第二个。然后第三个。。。
 
二。<script>的位置
1.
<! DOCTYPE html>
<html>
<head><title></title>
<script type="text/javascript" src="aaa.js"/>
<script type="text/javascript" src="aaa.js"/>
</head>
<body>
<!--这里放内容-->
</body>
<html>
 
这样放意味着必须等到所有javascript代码都下载,解释,完成后,才能开始呈现页面的内容(浏览器遇到body标签才开始呈现内容),如果很多javascript代码,会导致浏览器呈现页面时候明显延迟
,这段时间会一片空白,要避免则第二种方法
 
2.
<! DOCTYPE html>
<html>
<head><title></title>
</head>
<body>
<!--这里放内容-->
<script type="text/javascript" src="aaa.js"/>
<script type="text/javascript" src="aaa.js"/>
</body>
<html>
这样在解释javascript之前就会把页面呈现给用户
 
三,延迟脚步,异步脚本
 
1.defer
html4.01定义了defer属性,意思是脚本会被延迟到页面都解释完再运行
 
<! DOCTYPE html>
<html>
<head><title></title>
<script type="text/javascript" defer="defer "src="aaa.js"/>
<script type="text/javascript" defer="defer " src="aaa.js"/>
</head>
<body>
<!--这里放内容-->
</body>
<html>
 
虽然放在head标签里面,但是浏览器会遇到</html>后才解释,一般来说第二个延迟脚本会在第一个执行后再执行,但是有时并不一定,所以最好就一个延迟脚本
 defer至适合于外部src的脚本文件(HTML5已经明确规定),但是还有些浏览器并不支持,所以最好办法还是把<script>放在页面底部最佳选择
 
 2.async
1.和defer类似都只适用于外部脚本
2.不同时标志async的脚本不保证他们先后顺序执行,defer一般来说还按顺序,这个肯定不按顺序
 
 
 
三。在XHTML的语法
 
四。嵌入代码与外部文件
使用外部文件有以下优点
1.可维护
2.可缓存 浏览器根据具体的设置缓存链接的所有外部文件,也就是说,两个页面使用同一个文件,那么该文件只需要下载一次
3.适应未来 因为通过外部文件无需使用上面的XHTML或注视hack,XHTML包含外部文件语法是相同的
 
五。文档模式
开始(混杂模式、标准模式)
后来(混杂模式、(标准模式。准标准模式))准标准模式与标准模式非常类似,差异可以忽略不计
 
如果文档开始没有使用任何文档声明,则所有浏览器使用开启混杂模式
 
1.开启标准模式
 
2.开启准标准模式,可以使用过渡型和框架集型
 
 六。<NOSCRIPT>元素
 
1.浏览器不支持javascript
2.支持但是脚本被禁止
 
<html>
<head><title></title>
<script type="text/javascript" defer="defer "src="aaa.js"/>
<script type="text/javascript" defer="defer " src="aaa.js"/>
</head>
<body>
<noscript>
<p>本页面需要开启javascript</p>
</noscript>
</body>
<html>
 
假如禁止了javascript,p里面的文字会显示,假如允许,p里面的文字永远不会显示
 

 
 第三章 基本概念
 
 
 
本章内容 语法 数据类型 流控制语句 函数
 
目前 ECMA-262定义的第三版是各个浏览器实现最多的一个版本,第五版是接下来的实现。到2011年底还没完全实现,本文以第三版为基础,并以第五版变化作出说明
 
 
一。语法
 
1.区分大小写
 
2.标示符-变量,函数,属性,参数的名字
 
@首字母是字母、下划线或者美元符号$
@其他可以使字母、数字、下划线、和$
@不能用关键字、保留字、true,false、和null做标示符
 
3.注释
//  单行注释
 
/*
*
*
*/  块注释
 
 
4.严格模式
ECMAscript 5引入,是一种定义不同的解释和执行模式,把ECMAscript 3不确定的行为处理掉,而且某些不安全的操作也抛出错误,启用办法是顶部添加
"use strict"
 
在函数内部也可以,如
function aa(){
"use strict"
//函数体
}
 
5.语句
@   ;结尾
@   代码块,如
if(true){
 
}
 
6.关键字和保留字
 
 
7.变量
ECMAscript的变量是松散类型(就是可以保存任何类型的数据),用var来定义
@ var mes                    --mes为undefined
@ var mes=“hi”;  mes=11;   --可以,但是不推荐
 
@注意,用var操作符定义的变量将成为定义该变量的作用域中的局部变量
 
如在函数里面
1.
function a(){
var mes="HI";//局部变量
 
}
 
alert(mes);//错误
 
2.
function a(){
mes="HI";//全局变量
 
}
 
alert(mes);//  "HI"
省略了var,默认成了全局变量,但是不推荐
 
 
@一条语句定义多个如
var mes="hi",
      found=11,
      age=false;
 
@严格模式下,不能为eval或者arguments定义变量
 
 
8.数据类型
 
@5种简单数据类型
Undefined
Null
Boolean
Number
String
@1种复杂类型
Object
 
@typeof操作符---对于一个值使用typeof操作符可能使用下面字符串
 
"undefined"-------该值未定义
"boolean"   -------布尔
"string"      -------字符串
"number"  -------数字
"object"   -------对象
"object"   -------Null
"function"  -------函数
 
例子
var mes="aaaaaa";
alert(typeof mes);             ---"string" 
alert(typeof(mes));           --"string" 
alert(typeof 95);              --"number" 
 
@typeof操作符的对象可以使变量或者数值字面量
@typeof是操作符而不是函数,所以括号不是必须的
 
@@有时候typeof会返回一些疑惑但是技术上正确的值
 
@typeof null返回object,因为null被认为是一个空对象引用
@有些浏览器(Safai5-或Chrome7-)使用typeof 正则表达会返回function ,其他则object
 
@@技术角度上,函数在ECMA中script中时对象,不是一种数据类型,因此用typeof区分函数和其他对象
 
 
8.数据类型-Undefined
@只有一个值就是undefined
@使用var声明但是未加以初始化时就是undefined
 
1.
var mes;
alert(mes==undefined)    --true;
 
2.
var mes=undefined;
alert(mes==undefined)    --true;
 
3.
var mes;
//下面变量为声明
// age
alert(mes)    --“ undefined”
alert(age)    -- 报错
 
注意未声明和为初始化的概念
 
 
@@困惑的是
4.
var mes;
//下面变量为声明
// age
 
 
alert(typeof mes)    --"undefined";
alert(typeof age)    --"undefined";
 
对于未声明和为初始化都返回undefined
 
@@所以运用上面这点最好显示初始化变量是最好的明确选择,因为这样,当typeof就会返回undefined字符串,那么我们就知道该变量没有被声明而不是未初始化
var me==“”;
//下面变量未声明
// age
 
alert(typeof mes)    --"String";
alert(typeof age)    --"undefined"; 因为所有变量都初始化了,所以放回undefined肯定是未声明,而且这样不会报错
 
 
 
8.数据类型-Null
@也是只有一个值-null
@是一个空对象引用所以typeof Null是"object" 
@实际上,undefined值是派生于null的,所以
alert(null==undefined);   //true
 
@如果定义的是对象,最好先赋值为null,因为只需要检查null就知道已经是否保存一个对象的引用
var car=null;
if(car!=null){
}
 
@@无论在什么时候没必要把一个值显示设置为undefined,
@@null却相反,只要为明确保存什么对象时候,则设置为null
@@有助于区分null和undefined。
 
 
8.数据类型-Boolean
@只有两个值 true、false
@与数字值不是一回事,true不一定等于1,false不一定等于0
@区分大小写,True和False是标示符
@ECMA所有值都与Boolean有等价的值,可以使用Boolean()转换函数
 
var mes="hello";
var a= Boolean(mes);
 
规则
数据类型 转为true 转为false
Boolean true false
String 非空字符串 ""(空字符串)
Number 非0,包括无穷大 0和nan
object 任何对象 null
Undefined n/a undefined
 
 
@if语句自动执行Boolean转换
var mes="DF";
if(mes){
 
}
 
 
8.数据类型-Number
@整数和浮点型
@十进制,八进制,16进制
八进制第一位为0,后面为0到7,超过则前导0被忽略,后面为实际你只解释
 
var a=070   //八进制 56
var b=079 //八进制无效,解释为十进制 79 
 
十六进制前面为0x,后面0到9,a到f(可以大写)
 
var a =0xA     --十六进制的10
var b=0x1f     ----、十六进制的31
 
在进行算术计算时,所有八进制十六进制的值都会转换成十进制数值
 
 
@浮点数
var a=1.1;
var b=.1;    --有效但是不推荐
 
@由于浮点数需要的内存空间是整数值的两倍,所以ECMAscript有时会把 浮点数转换为整数值
 
var a=1.                   解释为1
var b =10.0;            解释为10
 
@科学计数法
var a=3.125e7    等于31250000
 
 
@@浮点数的精度为17位小数,进行算术计算时精确到远远不够整数
0.1+0.2不是0.3,而是 0.3000000000000004
所以
if(a+b==0.3){
alert("you got 0.3");
}
永远不会成立,不要这样做
 
@数据范围
1.Number.MIN_VALUE和Number.MIAX_VALUE,超出这两个范围则转换Infinity 正无穷 - Infinity 负无穷  
2.Infinity 正无穷 - Infinity 负无穷  ,某次计算返回这两个数,则无法参数下次计算
判断处于最大和最小范围之间可以使用isFinite()函数
var a=Number.MIAX_VALUE+Number.MIAX_VALUE;
alert(isFinite(a));//false;
 
 
 
@NaN值-非数值
1。任务语言除以0都会报错,停止程序
2。ECMAscript中 则返回NaN,而不会停止
3。NaN不等于NaN alert(NaN==NaN);--false
4。isNaN  判断这个数是否"不是数值",
alert(isNaN(NaN) )        //true
alert(isNaN(10))         //false 10是一个数值
alert(isNaN("10") )       //false  可以转换成10
alert(isNaN("blue") )     //true   这个字符不能转换成数值 
alert(isNaN(true) )       //false  可以转换成1
 
@@ isNaN也可以用于对象,首先调用对象的valueof(),确定是否能返回转换成数值,若不能,基于这个返回值再调用toString()方法,再测试返回值。
 
 
@转换函数   
Number()  任何数值
ParseInt()  把字符串转换成数值
parseFloat() 把字符串转换成数值
 
 
@@Number() 转换规则
1.若Boolean 则转换成0和1
2.若数字值,不变
3.null 则0
4.undefined 则NaN
5.对象则首先调用对象的valueof(),确定是否能返回转换成数值,若不能,基于这个返回值再调用toString()方法,再测试返回值
5.字符串则如下
   1.只包含数字(带正负),则转换为十进制,1--1,   123--123,   011--11
   2.浮点和上面一样
   3.若十六进制,0xf 则转换成十进制
   4.空字符串,则为0
   5. 其余则NaN
 
如下
var a=Number("DFSDF" )       --NaN
var b=Number("" )             -- 0
var c=Number( "000011")     -- 11
var d=Number( true)      --1
 
 
@@ParseInt()  转换规则
1.忽略前面空格,找到第一个字符串,若不是数字或者正负号,则NaN
2.如果第一个是数字,则一直解释下去,直到解释完或者遇到非数字
如1234aaa则转换为1234
22.5则转换为22
3.八进制,十六进制也能识别(严格模式会有问题)所以增加参数ParseInt(a,b),a为要转换的值,b为进数
var a=ParseInt("10",2)         10按二进制
var b=ParseInt("10",8)         10按八进制
var c=ParseInt("10",10)       10按十进制
var d=ParseInt("10",16)      10按十六进制
 
 
因为在严格模式ParseInt() 转换会造成混乱,所以最好加上参数
 
 
@@ParseFloat()  转换规则
1.和ParseInt一样,不过第一个小数点有效,第二个无效,如22.34.5转换为22.34
2.只解释10进制,所以没有第二个参数
3.如果字符窜包含一个可解释为整数的数(没有小数点或小数点后都是0),ParseFloat() 会返回整数
 
var a=ParseFloat"1234aaa")           //1234
var b=ParseFloat("0xA")                 // 0
var c=ParseFloat("22.5")                //22.5 
var d=ParseFloat(22.334.5)            // 22.334
var e=ParseFloat("0987.4")            //987.4
var f=ParseFloat("3.125e7")          // 31250000
 
 
8.数据类型-String
 
@String类型用于表示0或多个 16位Unicode字符组成的字符序列------字符串
@""或‘‘都一样,PHP则不同
@字符字面量--转义序列
字面量 含义
\n 换行
\t 制表
\b 空格
\r 回车
\f 进纸
\\ 斜杠
\‘ 单引号,在用单引号表示的字符串中使用,如‘He said,\‘HEY.\‘‘
\" 双引号,在用双引号表示的字符串中使用,如"He said,\"HEY.\""
\xnn 以十六制代码nn表示一个字符(n为0到F)。例如,\x41表示"A"
\unnnn 以十六制代码nnnn表示一个Unicode字符(n为0到F)。例如,\u03a3表示希腊字符"Σ"
 
 
@任何字符串长度都可以用length属性获取长度(如果字符串包含双字节字符,那么可能不会精确)
 
@ECMAScript 中字符串是不变的。创建之后若改变则先销毁再填充
 
@转换为字符串
1.toString(),几乎每一个值都有该方法,但是 null,undefined 没有该方法
数字的时候可以加入参数指定二进制八进制十进制十六进制
var a=10
a.toString()         --10
a.toString(2)      -- 1010
a.toString(8)       --12
a.toString(10)     --10
a.toString(16)     --a
 
2.String(),任何类型都可以包括null,undefined
1.如有有toString(),则调用
2.如果是null,则返回"null"
3.如果是undefined,则返回"undefined"
 
 
@最简单的转换时直接与字符串""相加
 
 
 
 
8.数据类型-Object
@一组数据和功能的集合--var 0=new Object();
 
@是所有它的实例的基础,其中包裹一下方法
1.constructor:保存用于创建当前对象的函数,var 0=new Object();构造函数就是Object();
 
2.hasOwnProperty(propertyName):用于检查给定的属性在当前对象实例中(而不是在实例的原型中)是否存在。参数必须是字符串,如:o. hasOwnProperty("name");
 
3.isPrototypeOf(Object):用于检查传入的对象是否是传入对象的原型
 
4.propertyIsEnumerable(propertyName):检查指定属性是否能用for-in语句,参数为字符串
 
5.toLocalString()
 
6.toString()
 
7.valueOf():返回对象的字符串、数值或布尔值表示
 
@@宿主对象可能继承也可能不继承Object,浏览器中的对象,如BOM和DOM中的对象都是宿主对象
 
 
 
 
 
5.操作符
 
 
5.1一元操作符
 
 
 
 
5.2位操作符
 
 
 
 
5.2布尔操作符
@一共有三个 非、与、或
 
@逻辑非 用!表示
1.与任何值都能返回一个布尔值,先转换为布尔值再求反
2。规则
&如果是对象,则false
&如果是空字符串,则true
&非空字符串,则false
&数值0,true
&非0包裹Infinity,则false
&null,true
&NaN,true
&undefined,true
如:
alert(!0)   true
alert(!NaN)  true
alert(!123)   false
 
 
 
@逻辑与   用&& 表示
1.可以应用任何类型的操作数,不仅仅是布尔值
2.在有一个操作数不是布尔值的情况下,逻辑与操作不一定返回布尔值,一下规则
&如果第一个操作数对象,则返回第二个操作数
&如果第二个操作数是对象,则只有第一个操作数为true的情况下才会返回该对象
&如果两个操作数都是对象,则返回第二个操作数
&如果有一个数为null,则返回null
&如果有一个数为NaN,则返回NaN
&如果有一个数为undefined,则返回undefined
 
3.逻辑与属于短路操作,如果第一个数能够决定结果,则不会对第二个求值
var a=true;
var b=(a&&bbbbbbbbbbbbb);bbbbbbbbbbb未定义会发生错误
 
var a=false;
var b=(a&&bbbbbbbbbbbbb);bbbbbbbbbbb未定义不会发生错误
 
 
 
@逻辑或   用||表示
1.与逻辑与类似,如果有一个操作数不是布尔值,逻辑或也不一定返回布尔值
2.
&如果第一个操作数对象,则返回第个操作数
&如果第一个操作数求值为false,则返回第二个操作数
&如果两个操作数都是对象,则返回第个操作数
&如果有两个数为null,则返回null
&如果有数为NaN,则返回NaN
&如果有数为undefined,则返回undefined
 
3.也是短路操作
 
 
 
 
5.4
1.乘性操作符--  *
&处理特殊值遵守下列规则
1.如果两个值都是数值则常规计算,若超过ECMA范围,则Infinity和-Infinity
2.如果有一个是NaN,则结果是NaN
3.如果Infinity与0相乘,则NaN
4.如果Infinity与非0相乘,则是Infinity或者-Infinity
5.如果是Infinity与Infinity则Infinity
6.如果一个数不是数值,则在后台调用number()转换其数值,再计算
 
 
2
除法操作符--  斜杠/
 

求模--%
 
 
 
5.5
1.加法操作符---+
如果都是数值则按照常规加法,然后根据下列返回
&如果一个为NaN,则结果为NaN
&如果Infinity加Infinity,则Infinity
&如果-Infinity加-Infinity则-Infinity
&如果Infinity加-Infinity 则NaN
 
如果有一个是字符串,那么按照下面
&如果两个操作数都是字符串,则前后拼接
&如果有一个是对象、数值或布尔值,则调用它们的toString()方法取得相应字符串值,如果按照前面字符串规则
&对于undefined和null,则分别调用string()函数取得字符串"undefined" 和"null"
 
alert(5+5);                //10
alert(5+"5");            //"55"
 
2.减法操作符---   -
如果都是数值则按照常规加法,然后根据下列返回
&如果一个为NaN,则结果为NaN
&如果Infinity加Infinity,则NaN
&如果-Infinity加-Infinity则NaN
&如果Infinity加-Infinity 则Infinity
&如果-Infinity加Infinity 则-Infinity
 
如果有一个是字符串、布尔值、null或undefined,则在后台调用Number()函数将其转换成数值,再根据前面做减法,如果转换成NaN,则结果为NaN
&如果有一个是对象,则调用对象的ValueOf()方法以取得表示对象的数值,如果是NaN,则结果是NaN,如果对象没有ValueOf()方法,则调用其toString()方法并将其得到的字符串转换为数值
 
5-trur==4    因为true转换为1
NaN-1=NaN
5-3=2
5-""=5   因为""转换成0
5-"2"=3  因为2转换成2
5-null=5   因为null转换成0
 
@@如果两个操作数都是字符串呢?
 
 
 
 
5.6 关系操作符
@小于<, 大于>, 小于等于<=, 大于等于>=,这几个关系操作符都返回一个布尔值
var result=5>3    //true
var result=5<3    //false
 
@与ECMAscript与其他操作符一样,当操作数使用非数值时候也要转换或完成某些奇怪的操作,规则:
&如果两个都是数值则数值比较
&如果两个都是字符串,则按照字符串对应的字符编码值
&如果一个数十操作数,则将另外一个操作数转换为一个数值,然后数值比较
&如果一个操作数十对象,则调用这个对象的valueof()用结果按照前面比较,如果没有ValueOf方法,则调用toString(),并用得到结果执行比较
&如果一个是布尔值,则先转换成数值再比较
 
 
&&比较字符串时候,大写字母的字符编码全部小于小写字母的字符编码
var result ="Black" < "alphabet"            //true 
&&如果比较两个数字字符串
var result="23"<"3"   //true,2的编码是50,3的编码是51
 
var result="23"<3   //false,字符23会转成23,数值与字符串比较时,字符串都会转换成数值
 
 
var result="a"<3   //false,因为"a"被转换成了NaN
 
var result=NaN<3   //false,因为任何操作数与NaN比较,结果都是false
var result= NaN >=3   //false
 
 
 
5.7 
1.相等操作符
@相等和不相等    ==和!=
1.都会先转换操作数(强制转换),然后再比较相等性
在转换不同类型时候,要遵守下列
1.如果有一个操作数是布尔值,则比较前转换为数值----false转换成0,true转为1
2.如果有一个操作数是字符串,另外一个是数值,则先字符串转换成数值再比较
3.如果一个操作数是对象,另外一个操作数不是,则调用对象的ValueOf方法用得到的基本类型值再比较
 
另外
1.null和undefined是相等的
2.比较值钱不能将null和undefined转换成其他值
3.如果一个数是NaN,相等则返回false,不相等则返回true(两个操作数都是NaN,相等操作符也返回false,因为按规定NaN不等于NaN)
4.如果两个操作数都是对象,则比较他们是不是同一个对象,如果都是指向同一对象,则返回true,否则false
表达式
null ==undefined true
"NaN"==NaN false
5==NaN false
NaN==NaN false
NaN!=NaN true
false==0 true
true==1 true
true==2 false
undefined==0 false
null==0 false
"5"==5 true
 
 
2.全等和不全等 ===   !==
@除了比较之前不转换操作数之外,全等与不全等没有什么区别
var result=("55"==55); ‘//true  因为转换后相等
var result=("55"===55) //false  因为不同数据类型不相等
 
@null==undefined会返回true,但null===undefined 返回false ,因为不同类型的值
 
 
5.8条件操作符
variable=boolean_expression ?trueValue:falseValue
如:
var max=(num1>num2) ? num1: num2;
 
 
5.9赋值操作符
 
 
5.10逗号操作符
 
@声明变量
var num1=1,num2=2.num3=3;
@
赋值-在用于赋值时,逗号操作符总会返回表达式中的最后一项,如
var num=(5,1,4,8,0);//num的值为0
 
 
 
 
6.语句
 
6.1 if 语句
@ECMAScript会自动调用Boolean()转换函数表达式
 
 
6.2 do - while
 
 
6.3 while语句
 
 
 
6.4 for语句
@
1.
var count =10;
for(var i=0;i<count;i++)
{
alert(i);
}
 
由于ECMAScript中不存在块级域,因此在循环内部定义的变量可以再外部访问,如
 
2.
var count =10;
for(var i=0;i<count;i++)
{
alert(i);
}
alert(i);//10
 
3.无限循环
for(; ;){
dosonmething();
}
 
 
6.5 for-in 语句
 
for(var propName in window){
dociment.write(propName );
}
 
如果迭代的对象的变量值为null或undefined,for-in语句会抛出错误
ECMAScript 5 更正了,但是为了兼容,循环时候做好判断
 
 
 
 
6.5 label语句
 
 
 
 
 
6.6break和continue语句
 
@与label语句联合使用
 
 
 
6.7 with 语句--
@将代码块的作用域设置到一个特定对象中
@定义with语句的目的主要是为了简化多次编写同一个对象
var qs=location.search.substring(1);
var hostName= location.hostname;
var url= location.href;
 
上面那几行代码包含location对象,使用with语句可以写成
with(location){
var qs=search.substring(1);
var hostName=hostname;
var url=href;
}
 
严格模式会语法错误,大量使用with会性能下降,还是建议不要用
 
 
6.8 switch语句---全等操作符
 
switch(i){
case 25:
case 35:  //25和35 合并了
alert(111);
break;
case 45:
break;
default:
alert("default");
}
 
@ECNAScript 相比其他语言,可以再switch语句中使用任何类型,无论是字符串还是对象都可以
@case的值不一定是常量,也可以是变量甚至表达式
 
var num=25;
 
switch(true){
    case num <0:
         alert(0);
            break;
    case num <=10 && num >0:
         alert(1);
            break;
    default:
         alert(2);
}
 
 
 
 
 
7.函数
1.
function  Name(arg0 ,arg1,.......argN){
    statements
}
 
@ECMAScript 中的函数在定义时不必制定是否返回值
 
@ 另外return 语句也可以不带任何返回值,这种情况下,函数停止执行后将返回undefined值
function  Name(arg0 ,arg1,.......argN){
    retrun;
}
 
@推荐做法要么永远返回值,要么永远不返回,否则会混乱
 
严格模式下限制
1.不能把函数命名为eval或arguments;
2.不能把参数命名为eval或arguments;
3.不能出现两个命名参数同名的情况
 
 
2.参数
@即便你定义的函数只接收两个参数,调用函数的时候未必一定传2个函数,可以传1,个或者3个,4个
@ECMAScript 中的参数在内部是用一个数组来表示,函数接收这个数组,而不在乎有多少个元素
@实际上,在函数体内可以通过arguments对象来访问这个参数数组
@其实arguments对象只是与数组类似(并不是Array实例),因为可以通过索引访问元素,arguments[0]第一个,arguments[1]第二个,因此
 function sayHi(name,message){
alert("hello:"+name+","+ message);
}
可改为
 function sayHi(name,message){
alert("hello:"+argument[0]+","+ argument[1]);
}
 
@ argument得length属性
 
function howManyArgs(){
alert(argument.length);
}
 
howManyArgs("123",45);     //2
howManyArgs();                  //0
howManyArgs(12);              //1
 
@可以利用这点
 
function doAdd(){
 
if(argument.length==1){
//do
}else if(argument.length==2){
//do
}
}
 
@有趣的一点
function doAdd(num1,num2){
argument[1]=10;
alert(argument[0]+num2);
}
 
&每次执行这个doAdd函数都会重写第二个参数,将第二个值修改10.因为argument对象中的值会自动反映到对应的命名参数,所以修改argument[1]自动修改num2,结果值都相同,不过他们的内存空间是独立的,但是值就同步。
&如果只是传入一个参数,那么argument[1]设置的值不会反映到命名参数中,因为argument对象的长度是有传入参数决定,而不是定义函数时候决定
 
&没有传递的命名参数将自动赋予undefined值,像定义变量但是没初始化一样。
 
 
@@严格模式下,上面的赋值会无效,即使设argument[1]=10,num2还是undefined,其次重写argument还会报错
 
@@没有重载
综上所述,ECMAScript函数没有重载,如果定义多个,则名字只属于最后一个定义的函数
 
 
 
 第四章 变量、作用域和内存问题
 
 
javascript变量松散类型的本质,可以定义任何类型和数据的规则,变量的值及其数据类型可以在脚本的生命周期内改变。
 
 
1.基本类型和引用类型
@基本类型指的是简单的数据段,引用类型值指那些可能由多个值构成的对象,
@基本数据类型:Underfined、Null、Boolean、Number、和String,都是按值访问
@引用类型,与其他语言不同,javascript不允许直接访问内存中的位置,不能直接操作对象的内存空间,引用类型的值是按引用访问的
 
1.1动态的属性(基本类型与引用)
var persion=new Object();
persion.name="Nicholas";
alert(persion.name);//"Nicholas";
 
 
var name="Nicholas";
persion.age=27;
alert(persion.age);//undefined ,不报错,但不推荐
 
 
 
1.2复制变量值(基本类型与引用)
 
@基本类型复制变量值时
var num1=5;
var num2=num1;
 
num2中的5与num1中的5是完全独立的,该值只是num1中5的一个副本。这两个值参与操作互不影响
复制前
 
  Number类型
   
num15 5
 
复制后
  Number类型
num2 5
num1 5
 
@引用类型复制变量值时
 
var obj1=new Object();
var obj2=obj1;
obj1.name="aaa";
alert(obj2.name); //aaa
 
复制引用变量时候。实际上就是复制一个指针,复制变量结束后,两个变量上将引用同一个对象,改变一个对象则会影响另外一个对象
 
技术分享
 
 
 
1.3传递参数
ECMAScript中的所有函数的参数都是按照值传递。就是说函数外部的值复制给函数内部的参数,就和吧一个值复制到另外一个值的变量一样。基本类型复制就像基本类型,引用类型复制就是引用类型
 
引用传递就是传递该引用,而不是复制多一份变量,值传递就是复制多一份变量。
 
@基本类型时候
functio addTen(num{
num +=10;
return num;
)
 
var count =20;
car result =addTen(count);
alert(count);//20,没有变化
alert(result );//30
 
 
@引用类型时候
 
function setNmae(obj){
obj.name="aaa";
}
var persion=new Object();
setName(persion);
alert(persion.name);  //aaa
 
为了证明是复制多一个,而不是直接传递引用,再看下面例子
引用传递就是传递该引用,而不是复制多一份变量,值传递就是复制多一份变量。
 
function setNmae(obj){
obj.name="aaa";
obj=new Object();
obj.name="bbb";
}
 
var persion=new Object();
setName(persion);
alert(persion.name);  //aaa
 
用引用的复制原理就能理解出来了,局部对象obj会在函数完毕后自动毁灭。
 
 
1.4 检测类型   instanceof
@用typeof操作符确定一个变量是字符串、数值、布尔值、还是undefined的最佳工具,如果是对象或者null。则返回object
 
@检测基本类型用typeof是得力助手,检测引用类型,很想知道什么类型对象所以用instanceof操作符
 
alert(person instanceof Object);  /变量是Object吗
alert(person instanceof Array);  /变量是Array吗
alert(person instanceof RegExp);  /变量是RegExp吗
 
规定,所有应用类型的值都是Object的实力,所以检测一个引用是否Object类型时,instanceof都会返回true,检测基本类型就是返回false,因为基本类型不是对象
 
@@typeof的兼容性-对正则应用typeof会返回function, 在ie和firefox则object
 
 
 
1.5 执行环境及作用
@每个执行环境都有一个与之关联的变量对象,全局化解是最外围的一个执行环境,ECMAscript根据宿舍不同,执行环境的对象也不一样,web浏览器全局环境就认为是window对象,该环境被销毁,保存在其中的变量和函数就随之摧毁
@函数也有自己执行环境,执行流进入函数时,函数环境就会被推入环境栈中,函数执行完毕后,栈会将环境弹出,把控制权还给之前的执行环境
@当代码在一个环境执行时候,会创建变量对象的一个作用域链。母的是保证执行环境有权访问所有变量和函数的有序访问
@作用域最前端,始终是当前执行单面所在环境的变量对象,如果环境是函数最开始时候只包含一个变量,即是arguments对象(这个对象在全局环境是不存在的),下一个变量来自包含(外部)环境,而再下一个变量则来自下一个包含环境,这样一直延续到全局执行环境,全局执行环境始终是作用域中的最后一个对象
 
@标示符解释是沿着作用域一级一级搜索的,搜索过程从作用域最前端开始,然后聚集向后回溯,直接找到(找不到就报错)
 
var color="blue";
 function changeColor(){
color="red";
}
changeColor();
alert(color);
 
这个例子中,changeColor作用域链包含两个对象:自己的变量arguments和全局变量对象,因为在作用域链向上搜索找到它
 
var color ="blue";
 function changeColor(){
var  anotherColor="red";
 
     function swapColors(){
          var tempColor= anotherColor;
                anotherColor=color;
                color= tempColor;
 
                //这里可以访问color、anotherColor和tempColor
     }
                //这里可以访问color、anotherColor不能访问tempColor
 
swapColors();
}
 
这里有三个执行环境:全局环境,changeColor局部环境,swapColors局部环境。
1:全局环境有一个变量color,一个函数changeColor,
2:changeColor的局部环境有一个名为anotherColor变量和函数swapColors,它能向上搜索访问全局环境中的变量函数。
3:swapColors的局部环境有变量tempColor,这变量只能在这个环境环境中访问,因为其他环境向上不能搜索到。而在swapColors都可以访问两个环境中的所有变量,因为它们是是swapColors的符父执行环境
技术分享
解释:内部环境可以通过作用链范文所有外部环境,外部环境则不能访问内部环境
 
 
 
1.6 延长作用链
 
在以下语句,作用链将会延长
1.try-catch中的catch语句
2.with语句
 
兼容问题,不推荐
 
 
1.7 没有块级作用域
 
@if和for
if(true){
var color="blue";
}
alert(color);//true
在其他语言if执行后所定义的变量最自动销毁,但在javascript中变量会添加到当前的执行环境(在这里是全局环境),所以。
for也是一样
 
 
@声明变量
1。使用var声明的变量会自动添加到最接近的环境中,函数内部就是函数的局部环境,(在with语句,最最近就是函数环境,with兼容问题和性能不建议使用就不描叙)
2.如果初始化变量没有使用var声明,该变量就会自动添加到全局环境(注意在严格模式中初始化未经声明的变量会导致错误)
 
下面两个例子(不是严格模式)
1.
function add(num1,num2){
var sum=sum1+sum2;
return sum;
}
var result=add(10,20); //30
alert(num);                  //会报错,因为函数里面为sum定义了var,那么sum就添加到函数的作用域
 
2.
function add(num1,num2){
sum=sum1+sum2;
return sum;
}
var result=add(10,20); //30
alert(num);         //30,因为sum初始化没有使用var关键字,于是调用完爱到底add()后,会添加到全局环境,所以可以执行不报错
 
注意:(注意在严格模式中初始化未经声明的变量会导致错误
 
 
 
@查询标识符
1.搜索会在作用链的最前端开始,向上一级一级搜索,知道匹配了该标示符,停止
 
var color="blue";
 
function getColor(){
var color="red";
return color;
}
 
alert(getColor());  //red
 
注意,如果不使用window.color都无法访问全局color对象
 
 
1.8垃圾回收
@标记清除
@引用计数
@性能问题
@管理内存
 
 
 
 
 
 
 
 
 

 

javascript高级程序设计

标签:

原文地址:http://www.cnblogs.com/crazylqy/p/4347747.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!