js高级
一、数据类型,
1.五种基本的数据类型
Undefined\Null\Boolean\Number\String
null是以前的js的一个bug,我们现在的js继承了过来。所以null也是值类型。
1种复杂基本类型: Object– 本质是一个无序的键值对列表(集合),也就是json格式,我们的object对象都是json格式的,只不过我们把这种格式的对象成为json。
2.function是对象,不是一种数据类型,在js里面没有类的概念
,平常women在c#里说的类的概念,在js里就是对象,对象的概念在js里叫对象的实例。
3.Undefined值是一个值(undefined),在使用var声明变量但未对其赋值(初始化)时,变量默认值为undefined,但与没声明的变量不一样。如:
var msg;
alert(msg==undefined);//true
alert(msg2);//错误
4.Null 只是一个值(null)。表示一个空对象指针。
alert(typeof null); //object
alert(null==undefined);//true
在保存对象的变量没有保存真正对象时,应该让该变量保存null值。
5.Boolean类型 - 两个字面值:true和false(区分大小写)
6.Number类型 – 整数和浮点数。*isNaN(NaN) parseInt("123blue") parseFloat Nan=Not a number 代表不是一个数字
7.String类型- 0至16位Unicode字符组成的字符序列。
8.Object类型 – 一组数据和功能的集合,也是顶级“父类”。 通过new关键字创建对象。包含成员:constructor 构造函数, hasOwnProperty(propertyName) 检查属性是否在当前对象中,isPrototypeOf(object) 检查对象是不是该对象原型,propertyIsEnumerable(propertyName) 检查属性是否能用for-in来循环,toString(),valueOf()
基本数据类型在内存中分别占用固定大小的空间,因为它们呗保存在栈内存中。
引用类型在栈中保存的是对象在堆内存中的地址。
这个跟C#中是一样的。
当我们定义一个字符串的时候,这个时候系统会马上定义一个包装类,然后把这个字符串放在包装类中,这个包装类除了存放这个值以外还有一大堆的方法。
var a="abc";
这个时候我们用a.会点出很多方法出来,这些方法根本就不是值类型的,其实这些都是包装类的,当我们点一个方法出来执行的时候,是在运行的时候立马把这个a放在一个包装类的对象里面,调用的是包装类对象的方法。当我们为这个a变量添加一个属性的时候,是加到包装类中的,当我们再次访问这个属性的时候就点不出来,因为当你点的时候又会创建一个新的包装类,这个包装类根本不存在这个属性。
例如:
a.name=“张三”;
这个时候在a.的时候并不会出来name这个属性。这就是为什么我们不能给值类型动态的添加属性,因为这个属性其实是添加到包装类中的。
二、函数
1.通过函数可以封装任意多条语句,在任何地方、任何时候调用。
定义函数时不需要指定返回值,因为任何函数在任何时候都可以通过return语句返回数据。
实际上未指定返回值的函数都返回一个undefined值。
三、函数参数arguments。
function test()
{
alert(arguments.length)
}
在我们调用的时候,当我们不传参数的时候,会弹出0。虽然我们没有指定参数,但是我们可以传递任意多个参数。
如test(1,2,3)这样会弹出3。
也就是说其实我们传入的参数是存放在arguments中的,但是它不是数组,我们可以这样验证,alert(arguments instanceof Array)会弹出false。
其实arguments是类数组的一个集合。
与其他语言不同,ECMAScript函数不介意传递进来多少个参数,也不在乎是什么类型。-- 因为参数在内部是用一个类数组来表示的,函数接收到的始终是个类数组。
上例看出,ECMAScript函数的一个重要特点:命名参数只提供便利,但不是必须的。
我们可以根据arguments来实现函数的重载。
arguments(包含所有传入方法的参数)特殊用法:arguments中有一个属性callee,是一个指针,指向拥有这个arguments对象的函数对象(就是当前函数对象的指针)。
例子:(阶乘函数)
function facorial(num)
{
if(num<=1) return 1;
else return num*factorial(num-1);
function facorial(num){
if(num<=1) return 1;
else return num*arguments.callee(num-1);
}
var another=facorial; facorial=function(){
return 1;}
alert(another(5)); alert(facorial(5));
大家可以运行这段代码,试试看又什么不一样。仔细想想为什么。
function setName(o)
{
o.name="张三";
o=new Object();
o.name="李四";
}
var c=new Object()
setName(c);
alert(c.name);
这个时候会打印张三。
当我们调用这个方法的时候,我们将c的引用传入到函数中,
那我们在函数中第一个代码操作的是c的引用。
当我们再new object的时候,我们的o指向的不再是c的引用,而是创建了一个新的堆空间,指向了这个新的对象。
函数中的局部变量在函数执行完后自动销毁。
四、
执行环境和作用域。
执行环境:定义了变量或函数有权访问的其他数据,决定了他们各自的行为。环境中所有代码执行完毕后该环境变量被销毁。
每个执行环境都有一个与之关联的 变量对象,环境中定义的所有变量和函数都保存在这个对象中。
我们可以这个来理解。
我们定义这样一个方法
function show()
{
alert(arguments.length);
var a=“张三”;
var c=a;
}
这个show方法在执行的时候,在里面有一个scope,这个变量保存了一个指针,这个指针指向了showScope变量,这个变量是作用域变量。这个变量里面其实就是一个数组,这个数组下标为0的是一个指针,这个指针指向了show方法的变量对象。
这个变量也是数组。
这个show方法的变量对象包含arguments,a,c还有一个this。
每个函数在被调用时都会创建自己的执行环境:当执行流进入一个函数时,函数的环境创建并入栈。执行完后栈将环境推出,把控制权返回给之前的执行环境。
所谓的作用域链就是我们上面图中的showhiscope。当我们执行方法的时候,就是通过查找作用域链来查找到变量等东西。
当代码在一个环境中执行时,会创建由变量对象构成的作用域链(scope chain)。用来保证对执行环境 有权访问的所有变量和函数的有序访问。作用域链前端始终是当前执行环境的变量对象。全局执行环境的变量对象始终都是作用域链的最后一个。
五、js函数里面没有块级作用域
function show()
{
var i=0;
if(i<=0)
{
var c=10;
i++
}
c=111;
alert(c);
}
按照常理来说我们在外面是不能访问到c的,但是在js函数里面中没有这种块级作用域,我们能够访问到。
但是在js函数外面是不能访问到的。在函数外面还是有这种作用域的。
六、引用类型:
引用类型是一种数据结构,用来将数据和功能组织到一起。常被成为“类”。但它不具备传统面向对象语言所支持的类和接口。
创建Object 的两种方式:1.new 关键字var s = new Object(); s.name="james"; s.age=27;var s = {}; s.name="james"; s.age=27;
2.对象 字面量表示法var s = {name:"james",age:27};var s2 = {"name":"james","age":27};
访问对象属性:s.name 或 s["name"]使用方括号的有点是可以通过变量来动态访问属性var proName="name"; alert(s[proName]);
七、数组的特点。
js中的Array的元素可以是任意类型。长度也是可变的。
下面的栈和队列都是模拟的
栈:先进后出,push(),pop();
队列:先进先出,push(0,shift(),unshift().
var arr=new Array();
arr.push(1);
arr.push(2);
alert(arr.pop());
alert(arr.pop());
alert(shift())
alert(shift())
分别打印2,1,1,2
数组的排序:
arr.push(1);
arr.push(3);
arr.push(2);
var s="";
for(i=0;i<arr.length;i++)
{
s=arr[i]+","
}
alert(s);
这里打印出来的是1,3,2
当我们下面使用sort方法
arr.sort()后,再循环就打印1,2,3。
其实我们在使用sort的时候可以看到,里面可以传一个参数,这个似乎就想到了C#中的集合的sort方法,我们可以传递一个委托来实现自定义的排序。
具体传参数的实现方法:
function mysort(x,y)
{
if(x>y) return 1;
else return 0
}
然后将这个方法传到sort方法的参数中。
,reverse()-翻转(将数组元素顺序倒过来)
concat()—连接数组的
var colors=["a","b"];
var newcolor=colors.concat("yellow",["c","d"]);
连接成一个新的数组。
八、
this引用的是函数据以执行操作的对象,也就是 函数在执行时所处的作用域(通俗:就是哪个对象.出了这个函数,那么函数里的this就代表哪个对象)
1.当在网页全局作用域调用函数时,this对象就是window
如: window.color="blue";
var o={color:"red"};
function sayColor(){
alert(this.color);
}
sColor();
o.sayColor=sayColor;
o.sayColor();