1992年Nombas开发出C-minus-minus(C--)的嵌入式脚本语言(最初绑定在CEnvi软件中).后将其更名ScriptEase.(客户端执行的语言)css
Netscape(网景)接收Nombas的理念,(Brendan Eich)在其Netscape Navigator 2.0产品中开发出一套livescript的脚本语言.Sun和Netscape共同完成.后更名叫Javascripthtml
微软随后模仿在其IE3.0的产品中搭载了一个JavaScript的克隆版叫Jscript.前端
为了统一三家,ECMA(欧洲计算机制造协会)定义了ECMA-262规范.国际标准化组织及国际电工委员会(ISO/IEC)也采纳 ECMAScript 做为标准(ISO/IEC-16262)。今后,Web 浏览器就开始努力(虽然有着不一样的程度的成功和失败)将 ECMAScript 做为 JavaScript 实现的基础。EcmaScript是规范.java
尽管 ECMAScript 是一个重要的标准,但它并非 JavaScript 惟一的部分,固然,也不是惟一被标准化的部分。实际上,一个完整的 JavaScript 实现是由如下 3 个不一样部分组成的:node
简单地说,ECMAScript 描述了如下内容:python
1 直接编写
<script> alert('hello yuan') </script> 2 导入文件 <script src="hello.js"></script>
1
2
3
|
x=5
y=6
z=x+y
|
在代数中,咱们使用字母(好比 x)来保存值(好比 5)。经过上面的表达式 z=x+y,咱们可以计算出 z 的值为 11。在 JavaScript 中,这些字母被称为变量。数组
那么如何在JS中定义使用变量呢?浏览器
一、声明变量时不用声明变量类型. 全都使用var关键字;app
1
|
var
a;<br>a=3;
|
二、一行能够声明多个变量.而且能够是不一样类型
1
|
var
name=
"yuan"
, age=20, job=
"lecturer"
;
|
三、声明变量时 能够不用var. 若是不用var 那么它是全局变量
四、变量命名,首字符只能是字母,下划线,$美圆符 三选一,余下的字符能够是下划线、美圆符号或任何字母或数字字符且区分大小写,x与X是两个变量
常量 :直接在程序中出现的数据值
标识符:
/* number ----- 数值 boolean ----- 布尔值 string ----- 字符串 undefined ----- undefined null ----- null *
整数:
在JavaScript中10进制的整数由数字的序列组成
精确表达的范围是
-9007199254740992 (-253) 到 9007199254740992 (253)
超出范围的整数,精确度将受影响
浮点数:
使用小数点记录数据
例如:3.4,5.6
使用指数记录数据
例如:4.3e23 = 4.3 x 1023
16进制和8进制数的表达:
16进制数据前面加上0x,八进制前面加0;16进制数是由0-9,A-F等16个字符组成;8进制数由0-7等8个数字组成
16进制和8进制与2进制的换算:
1
2
|
2进制: 1111 0011 1101 0100 <-----> 16进制:0xF3D4 <-----> 10进制:62420
2进制: 1 111 001 111 010 100 <-----> 8进制:0171724
|
是由Unicode字符、数字、标点符号组成的序列;字符串常量首尾由单引号或双引号括起;JavaScript中没有字符类型;经常使用特殊字符在字符串中的表达;
字符串中部分特殊字符必须加上右划线\;经常使用的转义字符 \n:换行 \':单引号 \":双引号 \\:右划线
Boolean类型仅有两个值:true和false,也表明1和0,实际运算中true=1,false=0
布尔值也能够看做on/off、yes/no、1/0对应true/false
Boolean值主要用于JavaScript的控制语句,例如:
if (x==1){ y=y+1; }else{ y=y-1; }
Undefined类型
Undefined 类型只有一个值,即 undefined。当声明的变量未初始化时,该变量的默认值是 undefined。
当函数无明确返回值时,返回的也是值 "undefined";
Null类型
另外一种只有一个值的类型是 Null,它只有一个专用值 null,即它的字面量。值 undefined 其实是从值 null 派生来的,所以 ECMAScript 把它们定义为相等的。
尽管这两个值相等,但它们的含义不一样。undefined 是声明了变量但未对其初始化时赋予该变量的值,null 则用于表示还没有存在的对象(在讨论 typeof 运算符时,简单地介绍过这一点)。若是函数或方法要返回的是对象,那么找不到该对象时,返回的一般是 null。
算术运算符:
+ - * / % ++ -- 比较运算符: > >= < <= != == === !== 逻辑运算符: && || ! 赋值运算符: = += -= *= /= 字符串运算符: + 链接,两边操做数有一个或两个是字符串就作链接运算
注意1: 自加自减
假如x=2,那么x++表达式执行后的值为3,x--表达式执行后的值为1;i++至关于i=i+1,i--至关于i=i-1;
递增和递减运算符能够放在变量前也能够放在变量后:--i
var i=10; console.log(i++); console.log(i); console.log(++i); console.log(i); console.log(i--); console.log(--i);
注意2: 单元运算符
1
2
3
|
- 除了能够表示减号还能够表示负号 例如:x=-y
+ 除了能够表示加法运算还能够用于字符串的链接 例如:
"abc"
+
"def"
=
"abcdef"
|
js不一样于python,是一门弱类型语言
注意3: NaN
var d="yuan"; d=+d; alert(d);//NaN:属于Number类型的一个特殊值,当遇到将字符串转成数字无效时,就会获得一个NaN数据 alert(typeof(d));//Number //NaN特色: var n=NaN; alert(n>3); alert(n<3); alert(n==3); alert(n==NaN); alert(n!=NaN);//NaN参与的全部的运算都是false,除了!=
1
|
> >= < <= != == === !==
|
用于控制语句时:
if (2>1){ // 3 0 false null undefined [] console.log("条件成立!") }
等号和非等号的同类运算符是全等号和非全等号。这两个运算符所作的与等号和非等号相同,只是它们在检查相等性前,不执行类型转换。
console.log(2==2);
console.log(2=="2"); console.log(2==="2"); console.log(2!=="2");
注意1:
注意2:
等性运算符:执行类型转换的规则以下:
若是一个运算数是 Boolean 值,在检查相等性以前,把它转换成数字值。false 转换成 0,true 为 1。 若是一个运算数是字符串,另外一个是数字,在检查相等性以前,要尝试把字符串转换成数字。 若是一个运算数是对象,另外一个是字符串,在检查相等性以前,要尝试把对象转换成字符串。 若是一个运算数是对象,另外一个是数字,在检查相等性以前,要尝试把对象转换成数字。 在比较时,该运算符还遵照下列规则: 值 null 和 undefined 相等。 在检查相等性时,不能把 null 和 undefined 转换成其余值。 若是某个运算数是 NaN,等号将返回 false,非等号将返回 true。 若是两个运算数都是对象,那么比较的是它们的引用值。若是两个运算数指向同一对象,那么等号返回 true,不然两个运算数不等。
if (2>1 && [1,2]){ console.log("条件与") } // 思考返回内容? console.log(1 && 3); console.log(0 && 3); console.log(0 || 3); console.log(2 || 3);
<script>
console.log(“星期一”);
console.log(“星期二”);
console.log(“星期三”);
</script>
if-else结构:
if (表达式){ 语句1; ...... } else{ 语句2; ..... }
功能说明:若是表达式的值为true则执行语句1,不然执行语句2
示例:
if-elif-else结构:
if (表达式1) { 语句1; }else if (表达式2){ 语句2; }else if (表达式3){ 语句3; } else{ 语句4; }
示例:
switch-case结构
switch基本格式
switch (表达式) { case 值1:语句1;break; case 值2:语句2;break; case 值3:语句3;break; default:语句4; }
示例:
switch(x){ case 1:y="星期一"; break; case 2:y="星期二"; break; case 3:y="星期三"; break; case 4:y="星期四"; break; case 5:y="星期五"; break; case 6:y="星期六"; break; case 7:y="星期日"; break; default: y="未定义"; }
switch比else if结构更加简洁清晰,使程序可读性更强,效率更高。
循环语句流程图
for循环:
语法规则:
for(初始表达式;条件表达式;自增或自减) { 执行语句 …… }
功能说明:实现条件循环,当条件成立时,执行语句1,不然跳出循环体
for循环的另外一种形式:
for( 变量 in 数组或对象) { 执行语句 …… }
while循环:
语法规则:
while (条件){ 语句1; ... }
功能说明:运行功能和for相似,当条件成立循环执行语句花括号{}内的语句,不然跳出循环;一样支持continue与break语句。
示例:
try { //这段代码从上往下运行,其中任何一个语句抛出异常该代码块就结束运行 } catch (e) { // 若是try代码块中抛出了异常,catch代码块中的代码就会被执行。 //e是一个局部变量,用来指向Error对象或者其余抛出的对象 } finally { //不管try中代码是否有异常抛出(甚至是try代码块中有return语句),finally代码块中始终会被执行。 }
注:主动抛出异常 throw Error('xxxx')
简介:
在JavaScript中除了null和undefined之外其余的数据类型都被定义成了对象,也能够用建立对象的方法定义变量,String、Math、Array、Date、RegExp都是JavaScript中重要的内置对象,在JavaScript程序大多数功能都是基于对象实现的。
<script language="javascript">
var aa=Number.MAX_VALUE; //利用数字对象获取可表示最大数 var bb=new String("hello JavaScript"); //建立字符串对象 var cc=new Date(); //建立日期对象 var dd=new Array("星期一","星期二","星期三","星期四"); //数组对象 </script>
字符串建立(两种方式)
① 变量 = “字符串”
② 字串对象名称 = new String (字符串)
1
2
|
var
str1=
"hello world"
;
var
str1=
new
String(
"hello word"
);
|
x.length ----获取字符串的长度
x.toLowerCase() ----转为小写
x.toUpperCase() ----转为大写
x.trim() ----去除字符串两边空格
----字符串查询方法
x.charAt(index) ----str1.charAt(index);----获取指定位置字符,其中index为要获取的字符索引
x.indexOf(findstr,index)----查询字符串位置
x.lastIndexOf(findstr)
x.match(regexp) ----match返回匹配字符串的数组,若是没有匹配则返回null
x.search(regexp) ----search返回匹配字符串的首字符位置索引
示例:
var str1="welcome to the world of JS!"; var str2=str1.match("world"); var str3=str1.search("world"); alert(str2[0]); // 结果为"world" alert(str3); // 结果为15 ----子字符串处理方法 x.substr(start, length) ----start表示开始位置,length表示截取长度 x.substring(start, end) ----end是结束位置 x.slice(start, end) ----切片操做字符串 示例: var str1="abcdefgh"; var str2=str1.slice(2,4); var str3=str1.slice(4); var str4=str1.slice(2,-1); var str5=str1.slice(-3,-1); alert(str2); //结果为"cd" alert(str3); //结果为"efgh" alert(str4); //结果为"cdefg" alert(str5); //结果为"fg" x.replace(findstr,tostr) ---- 字符串替换 x.split(); ----分割字符串 var str1="一,二,三,四,五,六,日"; var strArray=str1.split(","); alert(strArray[1]);//结果为"二" x.concat(addstr) ---- 拼接字符串
建立数组的三种方式:
建立方式1:
var arrname = [元素0,元素1,….]; // var arr=[1,2,3]; 建立方式2: var arrname = new Array(元素0,元素1,….); // var test=new Array(100,"a",true); 建立方式3: var arrname = new Array(长度); // 初始化数组对象: var cnweek=new Array(7); cnweek[0]="星期日"; cnweek[1]="星期一"; ... cnweek[6]="星期六";
建立二维数组:
join方法:
concat方法:
数组排序-reverse sort:
数组切片操做:
删除子数组:
数组的push和pop:
数组的shift和unshift:
总结js的数组特性:
//方法1:不指定参数 var nowd1=new Date(); alert(nowd1.toLocaleString( )); //方法2:参数为日期字符串 var nowd2=new Date("2004/3/20 11:12"); alert(nowd2.toLocaleString( )); var nowd3=new Date("04/03/20 11:12"); alert(nowd3.toLocaleString( )); //方法3:参数为毫秒数 var nowd3=new Date(5000); alert(nowd3.toLocaleString( )); alert(nowd3.toUTCString()); //方法4:参数为年月日小时分钟秒毫秒 var nowd4=new Date(2004,2,20,11,12,0,300); alert(nowd4.toLocaleString( ));//毫秒并不直接显示
获取日期和时间
getDate() 获取日
getDay () 获取星期
getMonth () 获取月(0-11) getFullYear () 获取完全年份 getYear () 获取年 getHours () 获取小时 getMinutes () 获取分钟 getSeconds () 获取秒 getMilliseconds () 获取毫秒 getTime () 返回累计毫秒数(从1970/1/1午夜)
实例练习:
//该对象中的属性方法 和数学有关.
abs(x) 返回数的绝对值。 exp(x) 返回 e 的指数。 floor(x)对数进行下舍入。 log(x) 返回数的天然对数(底为e)。 max(x,y) 返回 x 和 y 中的最高值。 min(x,y) 返回 x 和 y 中的最低值。 pow(x,y) 返回 x 的 y 次幂。 random() 返回 0 ~ 1 之间的随机数。 round(x) 把数四舍五入为最接近的整数。 sin(x) 返回数的正弦。 sqrt(x) 返回数的平方根。 tan(x) 返回角的正切。 //方法练习: //alert(Math.random()); // 得到随机数 0~1 不包括1. //alert(Math.round(1.5)); // 四舍五入 //练习:获取1-100的随机整数,包括1和100 //var num=Math.random(); //num=num*10; //num=Math.round(num); //alert(num) //============max min========================= /* alert(Math.max(1,2));// 2 alert(Math.min(1,2));// 1 */ //-------------pow-------------------------------- alert(Math.pow(2,4));// pow 计算参数1 的参数2 次方.
1
2
3
|
function
函数名 (参数){
<br> 函数体;
return
返回值;
}
|
功能说明:
可使用变量、常量或表达式做为函数调用的参数
函数由关键字function定义
函数名的定义规则与标识符一致,大小写是敏感的
返回值必须使用return
Function 类能够表示开发者定义的任何函数。
用 Function 类直接建立函数的语法以下:
1
|
var
函数名 =
new
Function(
"参数1"
,
"参数n"
,
"function_body"
);
|
虽然因为字符串的关系,第二种形式写起来有些困难,但有助于理解函数只不过是一种引用类型,它们的行为与用 Function 类明确建立的函数行为是相同的。
示例:
注意:js的函数加载执行与python不一样,它是总体加载完才会执行,因此执行函数放在函数声明上面或下面均可以:
如前所述,函数属于引用类型,因此它们也有属性和方法。
好比,ECMAScript 定义的属性 length 声明了函数指望的参数个数。
1
|
alert(func1.length)
|
window对象
全部浏览器都支持 window 对象。
概念上讲.一个html文档对应一个window对象.
功能上讲: 控制浏览器窗口的.
使用上讲: window对象不须要建立对象,直接使用便可.
alert() 显示带有一段消息和一个确认按钮的警告框。
confirm() 显示带有一段消息以及确认按钮和取消按钮的对话框。
prompt() 显示可提示用户输入的对话框。
open() 打开一个新的浏览器窗口或查找一个已命名的窗口。
close() 关闭浏览器窗口。
setInterval() 按照指定的周期(以毫秒计)来调用函数或计算表达式。
clearInterval() 取消由 setInterval() 设置的 timeout。
setTimeout() 在指定的毫秒数后调用函数或计算表达式。
clearTimeout() 取消由 setTimeout() 方法设置的 timeout。
scrollTo() 把内容滚动到指定的坐标。
一、alert confirm prompt以及open函数
示例:
二、setInterval,clearInterval
setInterval() 方法会不停地调用函数,直到 clearInterval() 被调用或窗口被关闭。由 setInterval() 返回的 ID 值可用做 clearInterval() 方法的参数。
1
2
|
语法:<br> setInterval(code,millisec)
其中,code为要调用的函数或要执行的代码串。millisec周期性执行或调用 code 之间的时间间隔,以毫秒计。
|
示例:
画dom树是为了展现文档中各个对象之间的关系,用于对象的导航。
HTML 文档中的每一个成分都是一个节点。
DOM 是这样规定的:
整个文档是一个文档节点
每一个 HTML 标签是一个元素节点
包含在 HTML 元素中的文本是文本节点
每个 HTML 属性是一个属性节点
其中,document与element节点是重点。
节点树中的节点彼此拥有层级关系。
父(parent),子(child)和同胞(sibling)等术语用于描述这些关系。父节点拥有子节点。同级的子节点被称为同胞(兄弟或姐妹)。
下面的图片展现了节点树的一部分,以及节点之间的关系:
访问 HTML 元素(节点),访问 HTML 元素等同于访问节点,咱们可以以不一样的方式来访问 HTML 元素。
直接查找节点
1
2
3
4
|
document.getElementById(“idname”)
document.getElementsByTagName(“tagname”)
document.getElementsByName(“name”)
document.getElementsByClassName(“name”)
|
注意:设计到寻找元素,注意<script>标签的位置!
导航节点属性
'''
parentElement // 父节点标签元素
children // 全部子标签
firstElementChild // 第一个子标签元素
lastElementChild // 最后一个子标签元素
nextElementtSibling // 下一个兄弟标签元素
previousElementSibling // 上一个兄弟标签元素 '''
注意,js中没有办法找到全部的兄弟标签!
建立节点:
1
|
createElement(标签名) :建立一个指定名称的元素。
|
例:var tag=document.createElement(“input")
tag.setAttribute('type','text');
添加节点:
1
2
3
4
5
|
追加一个子节点(做为最后的子节点)
somenode.appendChild(newnode)
把增长的节点放到某个节点的前边
somenode.insertBefore(newnode,某个节点);
|
删除节点:
1
|
removeChild():得到要删除的元素,经过父元素调用删除
|
替换节点:
1
|
somenode.replaceChild(newnode, 某个节点);
|
节点属性操做:
一、获取文本节点的值:innerText innerHTML
二、attribute操做
elementNode.setAttribute(name,value)
elementNode.getAttribute(属性名) <-------------->elementNode.属性名(DHTML) elementNode.removeAttribute(“属性名”);
三、value获取当前选中的value值
1.input
2.select (selectedIndex)
3.textarea
四、innerHTML 给节点添加html代码:
该方法不是w3c的标准,可是主流浏览器支持
tag.innerHTML = “<p>要显示内容</p>”;
五、关于class的操做:
1
2
3
|
elementNode.className
elementNode.classList.add
elementNode.classList.remove
|
六、改变css样式:
1
2
3
|
<p
id
=
"p2"
>Hello world!<
/
p>
document.getElementById(
"p2"
).style.color
=
"blue"
;
.style.fontSize
=
48px
|
onclick 当用户点击某个对象时调用的事件句柄。
ondblclick 当用户双击某个对象时调用的事件句柄。
onfocus 元素得到焦点。 练习:输入框
onblur 元素失去焦点。 应用场景:用于表单验证,用户离开某个输入框时,表明已经输入完了,咱们能够对它进行验证.
onchange 域的内容被改变。 应用场景:一般用于表单元素,当元素内容被改变时触发.(三级联动)
onkeydown 某个键盘按键被按下。 应用场景: 当用户在最后一个输入框按下回车按键时,表单提交.
onkeypress 某个键盘按键被按下并松开。
onkeyup 某个键盘按键被松开。
onload 一张页面或一幅图像完成加载。
onmousedown 鼠标按钮被按下。
onmousemove 鼠标被移动。
onmouseout 鼠标从某元素移开。
onmouseover 鼠标移到某元素之上。
onmouseleave 鼠标从元素离开
onselect 文本被选中。
onsubmit 确认按钮被点击。
方式1:
<div id="div" onclick="foo(this)">点我呀</div> <script> function foo(self){ // 形参不能是this; console.log("点你大爷!"); console.log(self); } </script>
方式2:
<p id="abc">试一试!</p> <script> var ele=document.getElementById("abc"); ele.onclick=function(){ console.log("ok"); console.log(this); // this直接用 }; </script>
一、onload:
onload 属性开发中 只给 body元素加.这个属性的触发 标志着 页面内容被加载完成.应用场景: 当有些事情咱们但愿页面加载完马上执行,那么可使用该事件属性.
二、onsubmit:
当表单在提交时触发. 该属性也只能给form元素使用.应用场景: 在表单提交前验证用户输入是否正确.若是验证失败.在该方法中咱们应该阻止表单的提交.
三、事件传播:
四、onselect:
五、onchange:
六、onkeydown:
Event 对象:Event 对象表明事件的状态,好比事件在其中发生的元素、键盘按键的状态、鼠标的位置、鼠标按钮的状态。
事件一般与函数结合使用,函数不会在事件发生前被执行!event对象在事件发生时系统已经建立好了,而且会在事件函数被调用时传给事件函数.咱们得到仅仅须要接收一下便可.好比onkeydown,咱们想知道哪一个键被按下了,须要问下event对象的属性,这里就时KeyCode.
七、onmouseout与onmouseleave事件的区别:
做用域是JavaScript最重要的概念之一,想要学好JavaScript就须要理解JavaScript做用域和做用域链的工做原理。
任何程序设计语言都有做用域的概念,简单的说,做用域就是变量与函数的可访问范围,即做用域控制着变量与函数的可见性和生命周期。在JavaScript中,变量的做用域有全局做用域和局部做用域两种。
做用域
在代码中任何地方都能访问到的对象拥有全局做用域,通常来讲一下几种情形拥有全局做用域:
(1)最外层函数和在最外层函数外面定义的变量拥有全局做用域
var name="yuan"; function foo(){ var age=23; function inner(){ console.log(age); } inner(); } console.log(name); // yuan //console.log(age); // Uncaught ReferenceError: age is not defined foo(); // 23 inner(); // Uncaught ReferenceError: inner is not defined
(2)全部末定义直接赋值的变量自动声明为拥有全局做用域,例如:
var name="yuan"; function foo(){ age=23; var sex="male" } foo(); console.log(age); // 23 console.log(sex); // sex is not defined
变量blog拥有全局做用域,而sex在函数外部没法访问到。
(3)全部window对象的属性拥有全局做用域
通常状况下,window对象的内置属性都都拥有全局做用域,例如window.alert()、window.location、window.top等等。
和全局做用域相反,局部做用域通常只在固定的代码片断内可访问到,最多见的例如函数内部,全部在一些地方也会看到有人把这种做用域成为函数做用域.
如示例1中的age与inner都只有局部做用域。(js中if、for没有本身的做用域)
在JavaScript中,函数也是对象,实际上,JavaScript里一切都是对象。函数对象和其它对象同样,拥有能够经过代码访问的属性和一系列仅供JavaScript引擎访问的内部属性。其中一个内部属性是[[Scope]],由ECMA-262标准第三版定义,该内部属性包含了函数被建立的做用域中对象的集合,这个集合被称为函数的做用域链,它决定了哪些数据能被函数访问。
please have a try:
//-----**********************例1********************************* var s=12; function f(){ console.log(s); var s=12; // if s=12 console.log(s) } f(); //-----**********************例2********************************* var s=10; function foo(){ console.log(s); var s=5; console.log(s); function s(){console.log("ok")}// 函数的定于或声明是在词法分析时完成的,执行时已再也不有任何操做 console.log(s); } foo(); //-----***********************例3******************************** function bar(age) { console.log(age); var age = 99;
var sex= 'male'; console.log(age); function age() {
alert(123) }; console.log(age);
return 100; } result=bar(5); //-----********************************************************
我相信你们必定会有想不到的结果,接下来咱们就以最复杂的例3来分析整个过程。
当一个函数建立后,它的做用域链会被建立此函数的做用域中可访问的数据对象填充。在函数bar建立时,它的做用域链中会填入一个全局对象,该全局对象包含了全部全局变量,以下图所示:
解析到函数调用时,即bar(5),会生成一个active object的对象,该对象包含了函数的全部局部变量、命名参数、参数集合以及this,而后此对象会被推入做用域链的前端,当运行期上下文被销毁,活动对象也随之销毁。新的做用域链以下图所示:
过程解析:
function bar(age) { console.log(age); var age = 99; var sex="male"; console.log(age); function age(){ alert(123); } ; console.log(age); return 100; } result=bar(5); 一 词法分析过程(涉及参数,局部变量声明,函数声明表达式): 1-1 、分析参数,有一个参数,造成一个 AO.age=undefine; 1-2 、接收参数 AO.age=5; 1-3 、分析变量声明,有一个 var age, 发现 AO 上面有一个 AO.age ,则不作任何处理 1-4 、分析变量声明,有一个 var sex,造成一个 AO.sex=undefine; 1-5 、分析函数声明,有一个 function age(){} 声明, 则把原有的 age 覆盖成 AO.age=function(){}; 二 执行过程: 2-1 、执行第一个 console.log(age) 时,当前的 AO.age 是一个函数,因此输出的一个函数 2-2 、这句 var age=99; 是对不 AO.age 的属性赋值, AO.age=99 ,因此在第二个输出的age是 99; 2-3 、同理第三个输出的是 99, 由于中间没有改变 age 值的语句了。 注意:执行阶段: function age(){ alert(123) } ; 不进行任何操做,将执行语句复制给age这部操做是在词法分析时,即运行前完成的。