javascript(三):对象
对象(object)是javascript中很重要的数据类型。对象是“键值对”的集合,同时也是无序的。(注意:对象结尾处有分号)
1 var ob1={ 2 a1:'name',//a1可以加引号或者不加 3 a2:100, 4 a3:function test(){}//末尾逗号(,)可加可不加 5 }; 6 var a1; 7 console.log(ob1['a1']); 8 console.log(ob1.a2); 9 var a2='a2'; 10 console.log(ob1[a2]);//此处a2被当做变量处理 11 for(var obj in ob1){ 12 console.log(ob1[obj]);//此处obj被当做字符串处理 13 }
对象的生成方法有三种:三种方法等价!
var ob2={}; var ob2=new Object(); var ob3=Object.create(Object.prototype);
关于对象键名:对象的键名是字符串,加不加引号均行;键名是数值,会自动转化为字符串;键名如果不符合标识名的条件,则需要加上引号!
注意:键名是字符串,但键值是任意形式(比如函数,整数,对象等)
1 var ob4={ 2 b1:'address',//键名未加引号 3 'b2':100,//键名加了引号 4 1e3:'age',//变为'1000' 5 '02x':[]//02x不符合标识符格式,需要加上引号! 6 };
对象里面的属性:可以动态添加,亦可动态删除
1 console.log('I\'m the division line -------------'); 2 var ob5={ 3 name:'Bob' 4 }; 5 ob5.name1='Alice'; 6 console.log(ob5.name1+" "+ob5.name); 7 delete ob5.name; 8 delete ob5.name1; 9 console.log(ob5.name1+' '+ob5.name);
运行结果:
对象中的“方法”:属性的值是函数,即对象里面的函数,称为“方法”!
1 var ob6={ 2 name:'cat', 3 //属性f是一个方法,即对象里面的函数 4 f:function test(a,b){ 5 return a<b ? a:b; 6 } 7 }; 8 console.log(ob6.name+' '+ob6.f(1,10));
运行结果:
对象引用:不同的变量名指向同一个对象,那么它们都是这个对象的引用,即指向同一个内存地址!修改其中一个变量,会影响到其它变量!
1 var obj={ 2 name:'Dog' 3 } 4 var o=obj; 5 console.log(o); 6 o.sex='male';//修改o,同时会影响obj 7 console.log(o,obj); 8 delete obj.name; 9 console.log(o,obj);
运行结果:
注意:当取消一个变量对对象的引用,则不会对另外一个变量造成影响!
1 obj=100; 2 console.log('此时obj=100,不是对象的引用了'); 3 console.log(obj,o);
运行结果:
但是这种引用只限于对象,其它原始数据类型的数据依然是传值引用,即值的拷贝!
一个值发生变化,另一个值不会跟着发生相应的变化!
1 var v1=10; 2 v2=v1; 3 console.log(v1,v2); 4 v2=100; 5 console.log(v1,v2); 6 v1=1000; 7 console.log(v1,v2);
运行结果:
查看对象中所有键名(属性):使用Object.keys()方法。
1 var obj2={ 2 name:'Array', 3 sex:'mail', 4 age:180 5 }; 6 console.log(Object.keys(obj2));
运行结果:
对象中的delete命令:一般删除对象中存在或不存在的键(属性),都返回true;除非对象设置configurable:false,此时delete后返回false。
同时delete不能删除继承来的属性。
1 var obj3={ 2 name:'xiaoming', 3 grade:'middle school', 4 age:20 5 }; 6 console.log(obj3.age); 7 console.log(delete obj3.age);//返回 true 8 console.log(obj3.age);//此时返回undefined 9 console.log(delete obj3.address);//返回true,纵然address键不存在 10 console.log(delete obj3.toString);//返回true,但是继承来的方法并未被删除 11 console.log(obj3.toString);
设置configurable:false后:
1 var obj4=Object.defineProperty({},'p',{ 2 value:100, 3 configurable:false 4 }); 5 console.log(delete obj4.p);//返回false
当然,前面学习变量申明时,就知道了delete 不能删除var申明的变量。(var 申明的是顶层对象,即window的属性,默认不可删除!)
检测对象中是否包含某个属性:in运算符!但是用in检测对象继承的属性,也返回true!!!
1 var obj5={ 2 language:"Go,Dart", 3 company:'google', 4 product:'chrome' 5 }; 6 console.log('------------'); 7 if('company' in obj5){ 8 console.log('yes'); 9 }else{ 10 console.log('no'); 11 } 12 console.log('toString' in obj5);//in,继承来的属性,返回true 13 console.log(obj5.hasOwnProperty('toString'));//继承来的属性,返回false
在JavaScript中,所有由var申明的全局变量都是顶层对象(window)的属性(--一切皆对象),都可以用in运算符检测。
1 console.log('wondow -------'); 2 b=1000; 3 console.log(b in window);//false 4 var a=100000; 5 console.log(a in window);//true 6 var x=1; 7 if(window.x){ 8 console.log('这种方法不能检测空字符串或null或undefined'); 9 } 10 if(x){ 11 //执行不下去了,报错,not definded 12 }
for...in循环遍历对象属性:
1.只遍历可遍历(enumerable)的属性,会跳过不可遍历的属性;
2.不仅遍历自身属性,还遍历继承属性。
with:操作同一个对象的多个属性时,提供书写上的一些方便。
1 var obj6={ 2 name:"apple", 3 name1:'blue', 4 name2:'cat' 5 }; 6 console.log('obj6-----'); 7 with(obj6){ 8 console.log(name);//返回"apple" 9 }
但是with很容易创造全局变量(即没有经过var申明):
1 with(obj6){ 2 age=100;//obj6中没有这个属性 3 console.log(age); 4 }
所以with缺点:无法判断变量如age是对象的一个属性,还是一个全局变量;这样不利于代码的排错和模块化;编译器无法对代码进行优化,只能运行时判断,拖慢了运行速度。因此不建议使用with,可以采用临时变量进行代替。
但是with的一个使用场景是:模板引擎变量替换。