- 引用类型:引用类型与Java中的类是有一定区别的,区别在引用类型不具备传统面向对象语言所支持的类和接口等基本结构。
- Object类型的定义,有两种方法:
1 var obj1=new Object(); 2 obj1.name="AAA"; 3 obj1.age=12; 4 5 var obj2={ 6 name:"BBB", 7 age:17 8 }
一般采用对象字面量语法,即第二种方法,这是最常用的对象定义方式。给人封装的感觉。并且当作参数传递给函数时比较直观。
1 function test(obj){ 2 if(typeof obj.name=='string'){ 3 console.log("name="+obj.name); 4 } 5 if(typeof obj.age=="number"){ 6 console.log("age="+obj.age) 7 } 8 } 9 10 test({name:"CCC",age:19});//name=CCC age=19
2. Array类型具有比较特殊的特征,比如它的每一组都可以保存任何类型的数据,它的创建方式如下:
1 var arr=new Array(); 2 var list=new Array(20); 3 var colors=new Array("blue","yellow","red"); 4 var nums=[1,2,3,4]; 5 6 nums[0]=11; 7 showArray(nums);//[11, 2, 3, 4] 8 nums[4]=5; 9 showArray(nums);//[11, 2, 3, 4, 5] 10 nums[-1]=-1; 11 showArray(nums);//[11, 2, 3, 4, 5, -1: -1], length is still 5. 12 nums.length=4; 13 showArray(nums);//[11, 2, 3, 4, -1: -1],delete from the last element in this array 14 nums.length=5; 15 showArray(nums);//[11, 2, 3, 4, empty, -1: -1], nums[4]=undefined; 16 console.log(nums instanceof Array);//true
这里包含的知识点为:创建数组的方法,数组下标越界的问题,数组的length属性修改的后果以及判断某个对象是否是数组的方法(用instanceof Array)
3. 数组的转换方法:toString()和valueOf()。toString()将数组转换成字符串,并以逗号分割后返回,不改变原数组。valueOf()显示数组元素,返回值类型和原数组一致。
1 var nums_2=[1,2,3,4,5] 2 console.log(nums_2.toString()+" type is:"+typeof(nums_2.toString()));//1,2,3,4,5 type is:string 3 console.log(nums_2.valueOf()+" type is:"+Array.isArray(nums_2.valueOf()));//1,2,3,4,5 type is:true
这里千万要区分开: typeof()和instanceof()这两个是一元运算符,而isArray()和valueOf()是数组的方法,在原型链中存在。
4. JS中的数组通过调用栈和队列的接口,即可实现栈或者队列类型的数据结构。pop()是从数组末尾取出一个元素,push()从数组末尾插入元素,shift()是从数组起始取出, unshift()是从数组起始插入。
5. 数组的排序方法sort(),sort()方法在底层为插入排序(元素数小于10)和快排(元素数大于10),并改变原数组,排序的一些特征通过以下代码来体现:
1 var forSort=[3,2,6,11,7,4,8,10,18,22,333]; 2 console.log(forSort.sort());//[10, 11, 18, 2, 3, 4, 6, 7, 8]这里默认排序比较的是字符串charCode码,即Unicode码的大小 3 4 function compare(a, b){ 5 return a-b; 6 }; 7 console.log(forSort.sort(compare));
6. 数组的操作方法非常多,主要包括:操作方法,位置方法,迭代方法和归并方法。整体上来说,所有的迭代方法 & concate() & slice() 不修改数组。
1 var arr_1=[1,2,3,4,5,6,7]; 2 var arr_forC=[8,9]; 3 console.log(arr_1.concat(arr_forC));// [1, 2, 3, 4, 5, 6, 7, 8, 9] 4 console.log(arr_1.slice(0,2));//[1, 2] 5 console.log(arr_1.slice(1));//[2, 3, 4, 5, 6, 7] 6 console.log(arr_1.slice(-1));//[7] 7 console.log(arr_1.slice(8));//[] 8 console.log(arr_1.slice(1.9));//[2, 3, 4, 5, 6, 7] 取下整 9 10 var arr_2=[1,2,3,4,5,6,7]; 11 console.log(arr_2.splice(1,2)+"\n"+"Now arr is: "+arr_2)//2,3 Now arr is: 1,4,5,6,7 this is "delete" 12 console.log(arr_2.splice(1,0,2,3)+"\n"+"Now arr is: "+arr_2)//Now arr is: 1,2,3,4,5,6,7 this is "add" 13 console.log(arr_2.splice(0,0,-1,0)+"\n"+"Now arr is: "+arr_2);//Now arr is: -1,0,1,2,3,4,5,6,7 14 console.log(arr_2.indexOf(7,0));//8,search 7 from the pos of 0 in this array.8 show 7's position in this array 15 16 var arr_3=[1,2,3,4,5,6,7]; 17 var every=arr_3.every(function(item){ 18 return item>2; 19 })// the returned value is boolean. All element must meet the requirement. 不改变原数组,不产生新数组。 20 21 var some=arr_3.some(function(item){ 22 return item>2; 23 })// the returend value is boolean.As long as more than one element meet the requirement. 24 25 var filter=arr_3.filter(function(item){ 26 return item>3; 27 })//按照标准选择性过滤后返回一个新数组 28 29 var map=arr_3.map(function(item){ 30 return item*2; 31 }) //数组每个元素操作之后,返回这个新数组。 32 33 var reduce=arr_3.reduce(function(pre,cur){ 34 return pre*cur; 35 });//start from the left of array. pre->previous element, cur->current element.
7. 时间Date类型。关于Date类型的方法非常多,可以直接查API。
8. 正则表达式RegExp。正则表达有两种方法,一种是test(),一种是exec()。可帮助我们实现很多模式匹配的问题。关于正则表达式的问题,会专门再开一页专门讨论。
9. Function函数类型。实质上是一个对象,函数名是指向函数的指针,并且变量在内存堆中。注意的是语法上,函数末尾有一个分号。使用function声明的函数,可以在之前就进行调用,因为JS引擎在解析时候,就将该函数放在了源代码树的顶层了。函数还具有嵌套的特性,一个函数嵌套另一个函数,这个涉及到函数的闭包,专门开一个专栏讨论。
10. 关于函数的内部对象问题。内部对象有arguments和this两个。arguments对象呢,有一个callee的属性,这个属性指向拥有这个arguments对象的函数,调用方法为arguments.callee。另一个this对象的存在与所在的执行环境有关。在全局环境的时候,this的引用对象就是window,在非全局环境的时候,this 的引用对象为所在函数执行的环境。
1 function factorial(num){ 2 if(num<=1){ 3 return 1; 4 } 5 else if(num>1){ 6 return num*arguments.callee(num-1)//这里是arguments!! 7 } 8 }
9 window.color="red"; 10 var obj={color:"blue",}; 11 function getColor(){ 12 console.log(this.color); 13 } 14 15 getColor();//red 16 17 obj.getColor=getColor; 18 obj.getColor();//blue
12. 另一个函数对象的属性为caller,相当于调用当前函数的调用函数。
1 function outer(){ 2 inner(); 3 } 4 function inner(){ 5 alert(arguments.callee.caller);//similar to inner.caller。 to call the caller of function inner(). 6 }
13. 因为函数名是指向函数的指针,所以声明一个新的变量,用等号相连接一个函数,则该新变量名则是一个新的指向函数的指针。再次注意,函数没有重载!
1 function a(x, y){ 2 console.log(x+y); 3 } 4 var b=a; 5 b(1,2);//2
12. 函数声明和函数表达式,在解析器执行时候,会先读取函数声明。如果遇到函数表达式,则读取到函数表达式那一行的时候才会开始读取这个函数。
13. 函数的属性和方法,下面做了一个小总结,不定期更新:

-
- length作为函数属性,可显示函数的传入参数个数。prototype属性是不可枚举的,像valueOf(), toString()都是prototype名下的。
1 function AA(sum){ 2 return sum; 3 }//AA.length=1; 4 function BB(a,b){ 5 return a+b; 6 }//BB.length=2 7 function CC(){ 8 return null; 9 }//CC.length=0;
-
- apply和call方法比较复杂。对Apply方法而言,简要说是在B函数中调用A函数,使得A在B中的环境运行,并且传入两个参数,一个参数是运行环境的作用域,另一个是参数数组。
1 function appA(num1){ 2 return num1*10; 3 } 4 function appB(ele1,ele2){ 5 return appA.apply(this, arguments)//arguments is the input element of appA, has nothing to do with appB. 6 } 7 console.log(appB(1));//10
这里的arguments是appA的参数,与appB有多少个参数无关。只需记住,apply是让一个函数在另一个函数的环境下运行的方法,传入参数也是被调用的函数所要求的。
call()方法与apply()类似,但是传入参数需要一个个用括号隔开。
-
- call方法比较强大的用处在于可扩展函数的作用域。
1 window.color="red"; 2 var obj={color:"blue"}; 3 function getColor(){ 4 console.log(this.color); 5 } 6 obj.objColor=getColor; 7 obj.objColor();//blue 8 9 getColor.call(window);//red 10 getColor.call(obj);//blue
-
- bind()方法可以结合创建函数实例B的时候,将原有的函数A和它的作用域传给函数B,这样无论在哪调用函数B,都会在这个绑定的作用域中运行。
1 window.name="X"; 2 var o={name:"Y"}; 3 function A(){ 4 console.log(this.name); 5 } 6 var B=A.bind(o); 7 B();//Y; 8 A();//X;
浙公网安备 33010602011771号