1. 复杂数据类型 Object
ECMAScript中的对象其实就是一组数据(属性)和功能(方法)的集合。 1) 创建Object实例: 1.使用构造函数创建,new Object() var person = new Object(); person.name = "briup"; person.age = 22;2.使用对象字面量表示法
不同的属性之间用','分割,属性名和属性值之间用':'分割 var person = { name : "briup", age : 22 }; 2) 访问对象属性 1.点表示法,右侧必须是以属性名称命名的简单标识符 person.name 2.中括号表示法,中括号中必须是一个计算结果为字符串的表达式,可以通过变量访问属性,如果属性名中包含语法错误的字符,或者属性名使用的是关键字或保留字,可以使用中括号 person["first name"] var a = "name"; person[a]; //既person["name"] person["first name"] 3) 删除属性 delete只是断开了属性和宿主对象的联系,而不会操作属性中的属性,并且delete只会删除自有属性,不能删除继承属性。在销毁对象时,为了防止内存泄露,遍历对象中的属性,依次删除所有属性。 语法:delete 属性访问表达式 例如: delete stu.name //删除学生对象中的name属性 4) 检测属性 in 检测某属性是否是某对象的自有属性或者是继承属性,是就返回true,否则返回false "toString" in student hasOwnProperty()检测给定的属性是否是对象的自有属性,对于继承属性将返回false var o = { x:1 } o.hasOwnProperty("x"); //true, x 为o的自有属性 o.hasOwnProperty("y"); //false,o 中不存在属性y o.hasOwnProperty("toString"); //false,toString为继承属性 propertyIsEnumerable() 检测给定的属性是否是该对象的自有属性,并且该属性是可枚举的通常由JS代码创建的属性都是可枚举的,但是可以使用特殊的方法改变可枚举性。 student.propertyIsEnumerable("toString") //false 不可枚举 5) Object属性及方法 Object 类型所具有的任何属性和方法也同样存在于其他对象中,任何对象继承于Object对象 Object中常用的方法: hasOwnProperty(propertyName); 检查给定的属性名是否是对象的自有属性, toString(); 返回对象的字符串表示 valueOf(); 返回对象的字符串,数值,布尔值的表示。 propertyIsEnumerable(propertyName); 检查给定的属性在当前对象实例中是否存在 constructor: 保存用户创建当前对象的函数 isPrototypeOf(object); 检查传入的对象是否是原型 toLocaleString(); 返回对象的字符串表示,该字符串与执行环境的地区对应 6) 对象序列化 对象序列化是指将对象的状态转换为字符串,也可以反序列化,将字符串还原为对象函数,RegExp,Error对象,undefined值不能序列化和反序列化。 JSON.stringify(obj) 将对象序列化为Json字符串,只能序列化对象可枚举的自有属性。 JSON.parse(jsonStr) 反序列化2. 函数
0)声明提升:
函数声明提升,所有的函数声明会提升至当前的作用域顶部
//函数声明--->函数声明会提升
function fnName(arg1,arg2){
//function body
}
//函数表达式--->函数表达式并不会被提升
var fnName=function(){
//function body
};
变量声明提升
alert("a" in window);
var a; ===>var a;
alert(""a" in window);
只有变量声明被提升而变量初始化不会提升(即变量直接赋值时在执行阶段创建)。
var a=1; ===>var a;
a=1;
alert(a); //undefined
alert(b);//error
b=10;
var a=20;
当变量声明并初始化,javascript会自动拆分变量声明和变量初始化
为什么没有提升变量初始化?
因为这样会影响变量值在代码执行期间导致不可预料的结果
必须知道和理解函数声明会覆盖变量声明,但不会覆盖变量初始化
function value(){
return 1;
}
var value;
alert(typeOf value); //function (typeOf返回一个表示类型的字符串)
//即使变量声明出现在函数声明之后,函数声明也会获得更高的优先权
function value(){
return 1;
}
var value=1;
alert(typeOf value); //Number 变量初始化覆盖了函数声明
var a=1; var a;
function foo(){ function foo(){
a=10; function a(){}
function a(){} ===> a=10;
} }
foo(); a=1;
alert(a); foo();
alert(a); //1
1) 作为值的函数 由于函数名本身就是变量,所以函数可以当做值来使用(参数,返回值)。 function callOther(fun,args){ return fun(args); } function show(msg){ alert(msg); } callOther(show,"哈哈"); //show为参数2) 作为返回值的函数 eg:多功能自定义排序函数 function myCompare(pro){ //函数将作为返回值返回 return function(obj1,obj2){ var val1 = obj1[pro]; var val2 = obj2[pro]; if(val1<val2){ return -1; }else if(val1>val2){ return 1; }else { return 0; } } } var data = [ { name : "aaa", age :12 },{ name:"ccc", age : 8 },{ name :"bbb", age : 71 } ]; console.log(data); data.sort(myCompare("age")); console.log(data); 3) 函数内部属性 1. arguments :是类数组对象,包含着传入函数中参数,arguments对象还有一个callee的属性,用来指向拥有这个arguments对象的函数 //实现多个数值类型的相加 var addAll = function(){ console.log(arguments.callee == addAll); // arguments = [1,2,3,5]; var total = 0; for(var key in arguments){ //通过索引获取值,key索引 0,1,2,3 var value = arguments[key]; total +=value; } return total; } var result = addAll(1,2,3,5,3,4); console.log("结果为:"+result); 例如: num的阶乘,使用递归函数 function factorial(num){ if(num<=1){ return 1; }else{ //return num * factorial(num-1); return num * arguments.callee(num-1); } } 2. this: 指向的是函数赖以执行的环境对象 window.color = "window"; var person = { color:"person" };function sayColor(){
alert(this.color); } sayColor(); //window对象调用,所以弹出 "window" person.sayColor = sayColor; //将该方法赋给person对象 person.sayColor();//使用person对象调用该方法,弹出"person" 4) 函数的属性 length: 表示函数希望接受的命名参数的个数 function say(msg){} //say.length 1 希望接受一个参数 function add(m,n){} //add.length 2 希望接受两个参数 prototype: 保存实例方法的真正所在。在自定义引用数据类型以及继承时非常重要。5) 函数的方法 this->该函数所在的环境对象 <script> var person = { name:"terry", add:function(){ } } person.add();function add(a,b){
alert(a+b); } add(1,2);// this->window => add.call(window,1,2); </script> apply : 参数(在其中运行函数的作用域,参数数组(Array,arguments)); call : 参数(在其中运行函数的作用域,参数列表) 这两个方法作用都是在特定的作用域中调用函数,实际上等于设置函数内部的this的值用法一:
function sum(m,n){ return m+n; } function call(m,n){ //return sum.apply(this,arguments); return sum.call(this,m,n); } alert(call(1,2)); 用法二: 扩充函数赖以运行的作用域 window.color = "window"; var person = { color:"person" };function sayColor(){
alert(this.color); } sayColor.call(this); sayColor.call(window); sayColor.call(person);3. 基本数据类型,引用数据类型
基本数据类型的变量: 可以直接操作保存在变量中的实际的值 参数传递的时候传递的是实际值 引用数据类型的变量: 不能直接操作对象的内存空间,实际上是在操作对象的引用。 可以为引用类型变量天极爱属性和方法,也可以改变和删除其属性和方法 参数传递的时候传递的是引用地址。 值传递 值的拷贝 引用传递 引用地址的拷贝var a = 3;
var p1 = { name:"larry", age:14, gender:"男", }; function changeA(a){ ++a;//4 } function changeName(p){ //b001 p.name ="tom" } function changeP(p){ //p = b001 //p = b002 p = { name:"jacky", age:14, gender:"男", } } console.log(p1);// b001 Object {name: "larry", age: 14, gender: "男"} changeName(p1); //b001 //changeP(p1); console.log(p1);//b001 Object {name: "tom", age: 14, gender: "男"}console.log("before a:"+a); //3
changeA(a); console.log("after a:"+a); //3