JavaScript---ECMA对象
1、对象的概念及分类
1.1 ECMAScript中没有类,但定义了“对象”,逻辑上等价于其他程序设计语言中的类。
var o = new Object();
1.2 本地对象(native object)和宿主对象(host object)
- 由ECMAScript定义的本地对象.独立于宿主环境的 ECMAScript 实现提供的对象.(native object)
- ECMAScript 实现提供的、独立于宿主环境的所有对象,在 ECMAScript 程序开始执行时出现.这意味着开发者不必明确实例化内置对象,它已被实例化了。ECMA-262 只定义了两个内置对象,即 Global 和 Math (它们也是本地对象,根据定义,每个内置对象都是本地对象)。(built-in object)
- 所有非本地对象都是宿主对象(host object),即由 ECMAScript 实现的宿主环境提供的对象。所有 BOM 和 DOM 对象都是宿主对象。
1.3 object 对象
ECMAScript 中的所有对象都由这个对象继承而来;Object 对象中的所有属性和方法都会出现在其他对象中
1 ToString() : 返回对象的原始字符串表示。 2 ValueOf() : 返回最适合该对象的原始值。对于许多对象,该方法返回的值都与 ToString() 的返回值相同。
1.4 内置对象(11种)
Array ,String , Date, Math, Boolean, Number Function, Global, Error, RegExp , Object
在JavaScript中除了null和undefined以外其他的数据类型都被定义成了对象,也可以用创建对象的方法定义变量,String、Math、Array、Date、RegExp都是JavaScript中重要的内置对象,在JavaScript程序大多数功能都是通过对象实现的
1 <script language="javascript"> 2 var aa=Number.MAX_VALUE; 3 //利用数字对象获取可表示最大数 4 var bb=new String("hello JavaScript"); 5 //创建字符串对象 6 var cc=new Date(); 7 //创建日期对象 8 var dd=new Array("星期一","星期二","星期三","星期四"); 9 //数组对象 10 </script>
2、 内置对象介绍
2.1 String对象
2.1.1 创建方式(2种)
自动创建字符串对象:
1 var str1="hello world"; 2 alert(str1.length); 3 alert(str1.substr(1,5));
调用字符串的对象属性或方法时自动创建对象,用完就丢弃
手工创建字符串对象
1 var str1= new String("hello word"); 2 alert(str1.length); 3 alert(str1.substr(1,3));
采用new创建字符串对象str1,全局有效
2.1.2 String对象的属性
1 获取字符串长度 2 length
var str1="String对象";
var str2="";
alert("str1长度 "+str1.length);
alert("str2长度 "+str2.length);
2.1.3 String对象的方法
String对象的方法(1) —— 格式编排方法
格式编排方法返回值列表
1 书写格式: 2 3 String对象提供了一组针对HTML格式的方法,如x.anchor()返回锚定义字符串<a>x</a>, 4 x.bold()返回粗体表示字符串<b>x</b>,x.sup()返回上标格式字符串<sup>x</sup>。 5 ----------------------------------------- 6 7 var x="hello"; 8 var y="x.italics():"+x.italics(); 9 document.write(y.fontsize(10));//<font size="10">x.italics():<i>hello</i></font>
String对象的方法(2)—— 大小写转换
1 var str1="AbcdEfgh"; 2 3 var str2=str1.toLowerCase(); 4 var str3=str1.toUpperCase(); 5 alert(str2); 6 //结果为"abcdefgh" 7 alert(str3); 8 //结果为"ABCDEFGH"
String对象的方法(3) —— 获取指定字符
1 书写格式 2 3 x.charAt(index) 4 5 x.charCodeAt(index) 6 7 使用注解 8 9 x代表字符串对象 10 index代表字符位置 11 index从0开始编号 12 charAt返回index位置的字符 13 charCodeAt返回index位置的Unicode编码 14 ---------------------- 15 var str1="welcome to the world of JS! 苑昊"; 16 17 var str2=str1.charAt(28); 18 var str3=str1.charCodeAt(28); 19 alert(str2); 20 //结果为"苑" 21 alert(str3); 22 //结果为33489
String对象的方法(4)—— 查询字符串
1 //书写格式 2 // 3 //x.indexOf(findstr,index) 4 //x.lastIndexOf(findstr) 5 //------------------------------------- 6 var str1="welcome to the world of JS!"; 7 8 var str2=str1.indexOf("l"); 9 var str3=str1.lastIndexOf("l"); 10 alert(str2); 11 //结果为2 12 alert(str3); 13 //结果为18 14 15 //-------*********************************************************------- 16 17 //书写格式 18 // 19 //x.match(regexp) 20 // 21 //x.search(regexp) 22 // 23 //使用注解 24 // 25 //x代表字符串对象 26 // 27 //regexp代表正则表达式或字符串 28 // 29 //match返回匹配字符串的数组,如果没有匹配则返回null 30 // 31 //search返回匹配字符串的首字符位置索引 32 //------------------------------------- 33 var str1="welcome to the world of JS!"; 34 35 var str2=str1.match("world"); 36 var str3=str1.search("world"); 37 alert(str2[0]); 38 //结果为"world" 39 alert(str3); 40 //结果为15
String对象的方法(5) ——子字符串处理
截取子字符串
1 //截取子字符串 2 // 3 //书写格式 4 // 5 //x.substr(start, length) 6 // 7 //x.substring(start, end) 8 // 9 //使用注解 10 // 11 //x代表字符串对象 12 // 13 //start表示开始位置 14 // 15 //length表示截取长度 16 // 17 //end是结束位置加1 18 // 19 //第一个字符位置为0 20 21 22 var str1="abcdefgh"; 23 var str2=str1.substr(2,4); 24 var str3=str1.substring(2,4); 25 alert(str2); 26 //结果为"cdef" 27 alert(str3); 28 //结果为"cd" 29 30 //-------*********************************************************------- 31 //x.slice(start, end) 32 33 34 var str1="abcdefgh"; 35 var str2=str1.slice(2,4); 36 var str3=str1.slice(4); 37 var str4=str1.slice(2,-1); 38 var str5=str1.slice(-3,-1); 39 alert(str2); 40 //结果为"cd" 41 alert(str3); 42 //结果为"efgh" 43 alert(str4); 44 //结果为"cdefg" 45 alert(str5); 46 //结果为"fg"
替换子字符串
1 //x.replace(findstr,tostr) 2 3 var str1="abcdefgh"; 4 var str2=str1.replace("cd","aaa"); 5 alert(str2); 6 //结果为"abaaaefgh"
分割字符串
1 var str1="一,二,三,四,五,六,日"; 2 3 var strArray=str1.split(","); 4 5 alert(strArray[1]); 6 //结果为"二"
连接字符串
1 //y=x.concat(addstr) 2 // 3 //使用注解 4 // 5 //x代表字符串对象 6 //addstr为添加字符串 7 //返回x+addstr字符串 8 9 var str1="abcd"; 10 var str2=str1.concat("efgh"); 11 12 alert(str2); 13 //结果为"abcdefgh"
2.2 Array 对象
创建数组对象
1 Array 对象用于在单个的变量中存储多个值。 2 语法: 3 4 创建方式1: 5 var a=[1,2,3]; 6 7 创建方式2: 8 new Array(); // 创建数组时允许指定元素个数也可以不指定元素个数。 9 new Array(size);//if 1个参数且为数字,即代表size,not content 10 初始化数组对象: 11 var cnweek=new Array(7); 12 cnweek[0]="星期日"; 13 cnweek[1]="星期一"; 14 ... 15 cnweek[6]="星期六"; 16 17 new Array(element0, element1, ..., elementn)//也可以直接在建立对象时初始化数组元素,元素类型允许不同 18 19 var test=new Array(100,"a",true);
创建二维数组
1 var cnweek=new Array(7); 2 for (var i=0;i<=6;i++){ 3 cnweek[i]=new Array(2); 4 } 5 cnweek[0][0]="星期日"; 6 cnweek[0][1]="Sunday"; 7 cnweek[1][0]="星期一"; 8 cnweek[1][1]="Monday"; 9 ... 10 cnweek[6][0]="星期六"; 11 cnweek[6][1]="Saturday";
Array对象的属性
获取数组元素的个数:length
1 var cnweek=new Array(7); 2 cnweek[0]="星期日"; 3 cnweek[1]="星期一"; 4 cnweek[2]="星期二"; 5 cnweek[3]="星期三"; 6 cnweek[4]="星期四"; 7 cnweek[5]="星期五"; 8 cnweek[6]="星期六"; 9 for (var i=0;i<cnweek.length;i++){ 10 document.write(cnweek[i]+" | "); 11 }
Array对象的方法
连接数组-join方法
1 //书写格式 2 //x.join(bystr) 3 //使用注解 4 // 5 //x代表数组对象 6 //bystr作为连接数组中元素的字符串 7 //返回连接后的字符串 8 //与字符串的split功能刚好相反 9 10 var arr1=[1, 2, 3, 4, 5, 6, 7]; 11 12 var str1=arr1.join("-"); 13 14 alert(str1); 15 //结果为"1-2-3-4-5-6-7"
连接数组-concat方法
1 //连接数组-concat方法 2 // 3 //x.concat(value,...) 4 5 6 var a = [1,2,3]; 7 var a = new Array(1,2,3); 8 var b=a.concat(4,5) ; 9 10 11 alert(a.toString()); 12 //返回结果为1,2,3 13 alert(b.toString()); 14 //返回结果为1,2,3,4,5
数组排序-reverse sort
1 //x.reverse() 2 //x.sort() 3 4 var arr1=[32, 12, 111, 444]; 5 //var arr1=["a","d","f","c"]; 6 7 arr1.reverse(); //颠倒数组元素 8 alert(arr1.toString()); 9 //结果为444,111,12,32 10 11 arr1.sort(); //排序数组元素 12 alert(arr1.toString()); 13 //结果为111,12,32,444 14 15 //------------------------------ 16 arr=[1,5,2,100]; 17 18 //arr.sort(); 19 //alert(arr); 20 //如果就想按着数字比较呢? 21 22 function intSort(a,b){ 23 if (a>b){ 24 return 1;//-1 25 } 26 else if(a<b){ 27 return -1;//1 28 } 29 else { 30 return 0 31 } 32 } 33 34 arr.sort(intSort); 35 36 alert(arr); 37 38 function IntSort(a,b){ 39 return a-b; 40 }
数组切片-slice
1 //x.slice(start, end) 2 // 3 //使用注解 4 // 5 //x代表数组对象 6 //start表示开始位置索引 7 //end是结束位置下一数组元素索引编号 8 //第一个数组元素索引为0 9 //start、end可为负数,-1代表最后一个数组元素 10 //end省略则相当于从start位置截取以后所有数组元素 11 12 var arr1=['a','b','c','d','e','f','g','h']; 13 var arr2=arr1.slice(2,4); 14 var arr3=arr1.slice(4); 15 var arr4=arr1.slice(2,-1); 16 17 alert(arr2.toString()); 18 //结果为"c,d" 19 alert(arr3.toString()); 20 //结果为"e,f,g,h" 21 alert(arr4.toString()); 22 //结果为"c,d,e,f,g"
删除子数组
1 //x. splice(start, deleteCount, value, ...) 2 // 3 //使用注解 4 // 5 //x代表数组对象 6 //splice的主要用途是对数组指定位置进行删除和插入 7 //start表示开始位置索引 8 //deleteCount删除数组元素的个数 9 //value表示在删除位置插入的数组元素 10 //value参数可以省略 11 12 13 var a = [1,2,3,4,5,6,7,8]; 14 a.splice(1,2); 15 //a变为 [1,4,5,6,7,8] 16 alert(a.toString()); 17 a.splice(1,1); 18 //a变为[1,5,6,7,8] 19 alert(a.toString()); 20 a.splice(1,0,2,3); 21 //a变为[1,2,3,5,6,7,8] 22 alert(a.toString());
数组的进出栈操作(1)
1 //push pop这两个方法模拟的是一个栈操作 2 3 //x.push(value, ...) 压栈 4 //x.pop() 弹栈 5 //使用注解 6 // 7 //x代表数组对象 8 //value可以为字符串、数字、数组等任何值 9 //push是将value值添加到数组x的结尾 10 //pop是将数组x的最后一个元素删除 11 12 13 var arr1=[1,2,3]; 14 arr1.push(4,5); 15 alert(arr1); 16 //结果为"1,2,3,4,5" 17 arr1.push([6,7]); 18 alert(arr1) 19 //结果为"1,2,3,4,5,6,7" 20 arr1.pop(); 21 alert(arr1); 22 //结果为"1,2,3,4,5"
数组的进出栈操作(2)
1 // unshift shift 2 //x.unshift(value,...) 3 //x.shift() 4 //使用注解 5 // 6 //x代表数组对象 7 //value可以为字符串、数字、数组等任何值 8 //unshift是将value值插入到数组x的开始 9 //shift是将数组x的第一个元素删除 10 11 var arr1=[1,2,3]; 12 arr1.unshift(4,5); 13 alert(arr1); 14 //结果为"4,5,1,2,3" 15 arr1. unshift([6,7]); 16 alert(arr1); 17 //结果为"6,7,4,5,1,2,3" 18 arr1.shift(); 19 alert(arr1); 20 //结果为"4,5,1,2,3"
总结js的数组特性:
1 // js中数组的特性 2 //java中数组的特性, 规定是什么类型的数组,就只能装什么类型.只有一种类型. 3 //js中的数组特性1: js中的数组可以装任意类型,没有任何限制. 4 //js中的数组特性2: js中的数组,长度是随着下标变化的.用到多长就有多长. 5 var arr5 = ['abc',123,1.14,true,null,undefined,new String('1213'),new Function('a','b','alert(a+b)')]; 6 /* alert(arr5.length);//8 7 arr5[10] = "hahaha"; 8 alert(arr5.length); //11 9 alert(arr5[9]);// undefined */
2.3 Date 对象
创建Date对象
1 //方法1:不指定参数 2 var nowd1=new Date(); 3 alert(nowd1.toLocaleString( )); 4 //方法2:参数为日期字符串 5 var nowd2=new Date("2004/3/20 11:12"); 6 alert(nowd2.toLocaleString( )); 7 var nowd3=new Date("04/03/20 11:12"); 8 alert(nowd3.toLocaleString( )); 9 //方法3:参数为毫秒数 10 var nowd3=new Date(5000); 11 alert(nowd3.toLocaleString( )); 12 alert(nowd3.toUTCString()); 13 14 //方法4:参数为年月日小时分钟秒毫秒 15 var nowd4=new Date(2004,2,20,11,12,0,300); 16 alert(nowd4.toLocaleString( )); 17 //毫秒并不直接显示
Date对象的方法—获取日期和时间
1 获取日期和时间 2 getDate() 获取日 3 getDay () 获取星期 4 getMonth () 获取月(0-11) 5 getFullYear () 获取完整年份 6 getYear () 获取年 7 getHours () 获取小时 8 getMinutes () 获取分钟 9 getSeconds () 获取秒 10 getMilliseconds () 获取毫秒 11 getTime () 返回累计毫秒数(从1970/1/1午夜)
实例:
1 function getCurrentDate(){ 2 //1. 创建Date对象 3 var date = new Date(); //没有填入任何参数那么就是当前时间 4 //2. 获得当前年份 5 var year = date.getFullYear(); 6 //3. 获得当前月份 js中月份是从0到11. 7 var month = date.getMonth()+1; 8 //4. 获得当前日 9 var day = date.getDate(); 10 //5. 获得当前小时 11 var hour = date.getHours(); 12 //6. 获得当前分钟 13 var min = date.getMinutes(); 14 //7. 获得当前秒 15 var sec = date.getSeconds(); 16 //8. 获得当前星期 17 var week = date.getDay(); //没有getWeek 18 // 2014年06月18日 15:40:30 星期三 19 return year+"年"+changeNum(month)+"月"+day+"日 "+hour+":"+min+":"+sec+" "+parseWeek(week); 20 } 21 22 alert(getCurrentDate()); 23 24 //解决 自动补齐成两位数字的方法 25 function changeNum(num){ 26 if(num < 10){ 27 return "0"+num; 28 }else{ 29 return num; 30 } 31 32 } 33 //将数字 0~6 转换成 星期日到星期六 34 function parseWeek(week){ 35 var arr = ["星期日","星期一","星期二","星期三","星期四","星期五","星期六"]; 36 // 0 1 2 3 ............. 37 return arr[week]; 38 }
Date对象的方法—设置日期和时间
1 //设置日期和时间 2 //setDate(day_of_month) 设置日 3 //setMonth (month) 设置月 4 //setFullYear (year) 设置年 5 //setHours (hour) 设置小时 6 //setMinutes (minute) 设置分钟 7 //setSeconds (second) 设置秒 8 //setMillliseconds (ms) 设置毫秒(0-999) 9 //setTime (allms) 设置累计毫秒(从1970/1/1午夜) 10 11 var x=new Date(); 12 x.setFullYear (1997); //设置年1997 13 x.setMonth(7); //设置月7 14 x.setDate(1); //设置日1 15 x.setHours(5); //设置小时5 16 x.setMinutes(12); //设置分钟12 17 x.setSeconds(54); //设置秒54 18 x.setMilliseconds(230); //设置毫秒230 19 document.write(x.toLocaleString( )+"<br>"); 20 //返回1997年8月1日5点12分54秒 21 22 x.setTime(870409430000); //设置累计毫秒数 23 document.write(x.toLocaleString( )+"<br>"); 24 //返回1997年8月1日12点23分50秒
Date对象的方法—日期和时间的转换
1 日期和时间的转换: 2 3 getTimezoneOffset():8个时区×15度×4分/度=480; 4 返回本地时间与GMT的时间差,以分钟为单位 5 toUTCString() 6 返回国际标准时间字符串 7 toLocalString() 8 返回本地格式时间字符串 9 Date.parse(x) 10 返回累计毫秒数(从1970/1/1午夜到本地时间) 11 Date.UTC(x) 12 返回累计毫秒数(从1970/1/1午夜到国际时间)
2.4 RegExp 对象
1 //RegExp对象 2 // 在表单验证时使用该对象验证用户填入的字符串是否符合规则. 3 //创建正则对象方式1 参数1 正则表达式 参数2 验证模式 g global / i 忽略大小写. //参数2一般填写g就可以,也有“gi”. 4 // 用户名 首字母必须是英文, 除了第一位其他只能是英文数字和_ . 长度最短不能少于6位 最长不能超过12位 5 //----------------------------创建方式1 6 /* var reg1 = new RegExp("^[a-zA-Z][a-zA-Z0-9_]{5,11}$","g"); 7 // 8 //验证字符串 9 var str = "bc123"; 10 alert(reg1.test(str));// true 11 12 //----------------------------创建方式2 /填写正则表达式/匹配模式; 13 var reg2 = /^[a-zA-Z][a-zA-Z0-9_]{5,11}$/g; 14 15 alert(reg2.test(str));// true 16 */ 17 //-------------------------------正则对象的方法------------------- 18 //test方法 ==> 测试一个字符串是否复合 正则规则. 返回值是true 和false. 19 20 //-------------------------String 中与正则结合的4个方法------------------. 21 // macth search split replace 22 var str = "hello world"; 23 24 //alert(str.match(/o/g)); //查找字符串中 复合正则的 内容. 25 //alert(str.search(/h/g));// 0 查找字符串中符合正则表达式的内容位置 26 //alert(str.split(/o/g)); // 按照正则表达式对字符串进行切割. 返回数组; 27 alert(str.replace(/o/g, "s")); // hells wsrld 对字符串按照正则进行替换.
2.5 Math 对象
1 //Math对象 2 //该对象中的属性方法 和数学有关. 3 //Math是内置对象 , 与Global的不同之处是, 在调用时 需要打出 "Math."前缀. 4 //属性学习: 5 //alert(Math.PI); 6 //方法学习: 7 //alert(Math.random()); // 获得随机数 0~1 不包括1. 8 //alert(Math.round(1.5)); // 四舍五入 9 //练习:获取1-100的随机整数,包括1和100 10 //var num=Math.random(); 11 //num=num*10; 12 //num=Math.round(num); 13 // alert(num) 14 //============max min========================= 15 /* alert(Math.max(1,2));// 2 16 alert(Math.min(1,2));// 1 */ 17 //-------------pow-------------------------------- 18 alert(Math.pow(2,4));// pow 计算参数1 的参数2 次方. 19 20 21 22 23 abs(x) 返回数的绝对值。 24 exp(x) 返回 e 的指数。 25 floor(x)对数进行下舍入。 26 log(x) 返回数的自然对数(底为e)。 27 max(x,y) 返回 x 和 y 中的最高值。 28 min(x,y) 返回 x 和 y 中的最低值。 29 pow(x,y) 返回 x 的 y 次幂。 30 random() 返回 0 ~ 1 之间的随机数。 31 round(x) 把数四舍五入为最接近的整数。 32 sin(x) 返回数的正弦。 33 sqrt(x) 返回数的平方根。 34 tan(x) 返回角的正切。
2.6 Function 对象
函数的定义:
1 function 函数名 (参数){ 函数体; 2 return 返回值; 3 }
功能说明:
- 可以使用变量、常量或表达式作为函数调用的参数
- 函数由关键字function定义
- 函数名的定义规则与标识符一致,大小写是敏感的
- 返回值必须使用return
Function 类可以表示开发者定义的任何函数。
用 Function 类直接创建函数的语法如下:
1 function 函数名 (参数){ 2 函数体; 3 return 返回值; 4 } 5 //another way: 6 var 函数名 = new Function("参数1","参数n","function_body");
虽然由于字符串的关系,第二种形式写起来有些困难,但有助于理解函数只不过是一种引用类型,它们的行为与用 Function 类明确创建的函数行为是相同的。
注意:js的函数加载执行与python不同,它是整体加载完才会执行,所以执行函数放在函数声明上面或下面都可以。
Function 对象的 length 属性
如前所述,函数属于引用类型,所以它们也有属性和方法。
比如,ECMAScript 定义的属性 length 声明了函数期望的参数个数。
1 alert(func1.length)
运算符void()作用:拦截方法的返回值
函数的调用
1 function func1(a,b){ 2 3 alert(a+b); 4 } 5 6 func1(1,2); //3 7 func1(1,2,3);//3 8 func1(1); //NaN 9 func1(); //NaN 10 11 //只要函数名写对即可,参数怎么填都不报错. 12 13 -------------------面试题----------- 14 function a(a,b){ 15 alert(a+b); 16 } 17 18 var a=1; 19 var b=2; 20 a(a,b)
函数的内置对象arguments
1 function add(a,b){ 2 3 console.log(a+b);//3 4 console.log(arguments.length);//2 5 console.log(arguments);//[1,2] 6 7 } 8 add(1,2) 9 10 ------------------arguments的用处1 ------------------ 11 function nxAdd(){ 12 var result=0; 13 for (var num in arguments){ 14 result+=arguments[num] 15 } 16 alert(result) 17 18 } 19 20 nxAdd(1,2,3,4,5) 21 22 // ------------------arguments的用处2 ------------------ 23 24 function f(a,b,c){ 25 if (arguments.length!=3){ 26 throw new Error("function f called with "+arguments.length+" arguments,but it just need 3 arguments") 27 } 28 else { 29 alert("success!") 30 } 31 } 32 33 f(1,2,3,4,5)
匿名函数
1 // 匿名函数 2 var func = function(arg){ 3 return "tony"; 4 } 5 6 // 匿名函数的应用 7 (function(){ 8 alert("tony"); 9 } )() 10 11 (function(arg){ 12 console.log(arg); 13 })('123')
补充:函数的作用域、作用域链和闭包
作用域:
JavaScript 中以函数作为作用域。
JavaScript 函数在被调用之前,作用域链已经存在。
JavaScript 中声明提前。
1 function fun(){ 2 // var s; (暗含) 3 4 console.log(s); 5 var s = "Hme"; 6 } 7 fun()
闭包:
1 var city = 'beijing'; 2 3 function func(){ 4 var city = "shanghai"; 5 function inner(){ 6 // var city = "langfang"; 7 console.log(city); 8 } 9 return inner; 10 } 11 var ret = func(); 12 ret();
作用域链(Scope Chain):
在JavaScript中,函数也是对象,实际上,JavaScript里一切都是对象。函数对象和其它对象一样,拥有可以通过代码访问的属性和一系列仅供JavaScript引擎访问的内部属性。其中一个内部属性是[[Scope]],由ECMA-262标准第三版定义,该内部属性包含了函数被创建的作用域中对象的集合,这个集合被称为函数的作用域链,它决定了哪些数据能被函数访问。
1 var x=1; 2 function foo() { 3 var y = 2; 4 5 function bar() { 6 var z = 3; 7 } 8 } 9 10 #bar的作用域链: barScopeChain=[bar.AO, foo.AO, global.VO]; 11 12 #foo的作用域链: fooScopeChain=[foo.Ao, global.VO];
AO 、VO
1 什么是AO,VO? 2 在函数创建时,每个函数都会创建一个活动对象Active Object(AO),全局对象为Global Object(VO),创建函数的过程也就是为这个对象添加属性的过程,作用域链就是由这些绑定了属性的活动对象构成的。 3 例如:找x变量;bar函数在搜寻变量x的过程中,先从自身AO对象上找,如果bar.AO存在这个属性,那么会直接使用这个属性的值,如果不存在,则会转到父级函数的AO对象,也就是foo.AO 4 如果找到x属性则使用,找不到继续 在global.VO对象查找,找到x的属性,返回属性值。如果在global.VO中没有找到,则会抛出异常ReferenceError 5 6 执行上下文。 7 函数在执行时会创建一个称为“执行上下文(execution context)”的内部对象,执行上下文定义了函数 8 执行时的环境。每个执行上下文都有自己的作用域链,用于标识符解析,当执行上下文被创建时,而它的作用 9 域链初始化为当前运行函数的[[Scope]]所包含的对象。 10 函数执行 11 在函数执行过程中,每遇到一个变量,都会检索从哪里获取和存储数据,该过程从作用域链头部,也就是从活 12 动对象开始搜索,查找同名的标识符,如果找到了就使用这个标识符对应的变量,如果没有则继续搜索作用域 13 链中的下一个对象,如果搜索完所有对象都未找到,则认为该标识符未定义,函数执行过程中,每个标识符都 14 要经历这样的搜索过程。
上一篇: SQL Server 创建和修改数据表