JavaScript中除了原始类型,null,undefined之外就是对象了,对象是属性的集合,每个属性都是由键值对(值可以是原始值,比如说是数字,字符串,也可以是对象)构成的。对象又可分为构造器对象和单体内置对象。
普通的对象是命名值的无序集合,但是通过不同的构造器。其中包括对象Object、函数Function、日期Date、数组Array、错误Error、正则RegExp。下面我们来分析对象。
一、对象Object
对象可以看成是属性无序集合,每一个属性都是一个键值对。属性名称是字符串,所以我们可以把对象看成是从字符串到值的映射。除了可以保持自有的属性,javascript对象还可以从原型上继续属性。对象的方法通常是继承的属性。这一种"原型式继承"是javascript的核心特征。
对象最常见的用法是创建(create),设置(set),查找(query),删除(delete),检测(test)和枚举(enumerate)它的属性。
1、对象的创建
有以下三种方法来创建对象。new构造函数,对象直接量和Object.create()函数。下在来一步步分析。
a.对象直接量
这是创建对象最简单的方式。对象直接量是由若干键值对组成的映射表,键值对中间用冒号分隔,键值对之间用逗号分开,整个的映射表用花括号括起来。属性名可以javascript标识符也可以是字符串直接量。属性值可以是任意类型的javascript表达式。
对象直接量是一个表达式,这个表达式的每次运算都创建并初始化一个新的对象。每次计算对象直接量的时候,也会计算它的相对应的值。也就是说,如果在一个重复调用的函数循环体内使用了对象直接量,它将创建很多新对象,且每次创建的对象的属性值也有可能不同。
<script>
var Person={
age:18,
sex:'男',
work:teacher,
}
</script>
b.new构造函数
new运算符创建并初创建化一个新对象,关键字new后跟随一个函数调用。这里的函数称做是构造函数,构造函数用以初始化一个新创建的对象,javascript语言核心中的原始类型都包含内构造函数。
<script>
var person = new Object();
//如是不给构造函数传递参数可以不加花括号 var person=new Object();
person.name = 'peng';
person.age = 18;
//创建无属性的空对象
var code1 = new Object();
var code2 = new Object(undefined);
var code3 = new Object(null);
console.log(typeof code1, typeof code2, typeof code3); //object object object
//如是该参数是一个对象,则直接返回这个对象
var n = { a: 1 };
var m = new Object(n);
console.log(n === m);//true
</script>
c.Object.create()函数
es5定义了一个名为Object.create()的方法,它创建一个新对象,第一个参数就是这个对象的原型,第二个可选参数用以对对象的属性进行进一步描述。它多用于继承的时候。
也可以通过传入参数null来创建一个没有原型的新对象,但是通过这种方式创建的对象不会继承任何东西,甚至不包括基础方法。
如果想创建一个普通的空对象(比如通过{}或new Object()创建的对象),需要传入Object.prototype。
Object.create()方法的第二个参数是属性描述符
<script>
var n=Object.create({a:1,b:2});//n继承了属性的a,b
console.log(n.a);//1
var m=Object.create(null);
var o={};
console.log(Number(o));//NaN
// console.log(Number(m));//报错
var p=Object.create(Object.prototype);
var p1={};
console.log(Number(p)); //NaN
console.log(Number(p1));//NaN
</script>
2、对象的组成
对象是属性的无序集合,由键值对组成
键名:对象的所有键名都是字符串,不加引号也可以,如是不是字符串的话也会自动转成字符串(要符合标识符命名的规则)。
属性值:属性值可以是任何类型的表达式,最终表达式的结果就是属性值的结果,如果函数值为函数的话,那就把这个属性称之为方法
<script>
var o={
a:1,
'b':2,
'12':4,
c:1+3,
f:function(x){
return 2*x;
}
}
console.log(o.a,o.b,o[12],o.c);//1 2 4 4
console.log(o.f(3));//6
</script>
3、对象的引用
如果不同的变量名指向同一个对象,那它们都是这个对象的引用,也就是说指向同一个内存地址,修改其中一个变量,会影响到其它所有的变量。如果取消一个变量对于原对象的引用,不会影响到另一个变量。
<script>
var o1={};
var o2=o1;
o1.a=1;
o2.b=2;
console.log(o1.b,o2.a);//2 1
o1=null;
console.log(o1,o2)//null {a: 1, b: 2}
</script>
4、实例方法
toString() 它将返回一个表示调用这个方法的对象值的字符串。
toLocaleString() 返回一个表示这个对象的本地化字符串
valueOf() 返回当前对象
<script>
var o1=new Object();
var o2={a:1};
console.log(o1.toString(),o2.toString());//[object Object] [object Object]
console.log(o2.toLocaleString());//[object Object]
console.log(o1.valueOf());//{}
</script>
二、属性的查询和设置
1.获取属性
我们可以通过点(.)或者是方括号([])运算符来获取属性的值。表示的的意思。
点(.)运算符
点运算符是很多面向对象语句的通用写法,因为比较的简单,所以常用。通过点运算符访问对象的属性时,属性名用一个标识符来表示,标识符要符合变量命名规则。
方括号([])运算符
当通过方括号运算符来访问对象的属性时,属性名通过字符串来表示。字符串是js的数据类型,在程序运行中可以修改和创建。
使用方括号运算符的优点:可以通过变量来访问属性,属性名称可以是特殊的标识符。
在方括号运算符内可以使用表达式,在es6中新增了可计算属性名,可以在文字中使用[]包裹一个表达式来当成属性。
查询一个不存在的属性不会报错,而是返回undefined.但是如果是对象不存在,再查询这个不存在对象的属性就会报错(可以利用这一点,来检查一个全局变量是否被声明)。
<script>
var a = 1;
var o = {
p: 'hello world',
m: 'helloworld',
font_size: '123',
[a + 2]: 'abc'
}
console.log(o.p);//hello world
console.log(o['m']);//helloworld
console.log(o['font_size']); //123
console.log(o[3]);//abc
console.log(o.b);//undefined
console(a.n);//报错
</script>
例子::点击按钮获取输入框中属性名称和属性值,对div设置
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> <style> div{ width: 100px;height: 100px;background-color: greenyellow; } </style> </head> <body> <script> window.onload=function(){ var text1=document.getElementById('text1'); var text2=document.getElementById('text2'); var btn=document.getElementById('btn'); var box=document.getElementById('box'); btn.onclick=function(){ var name=text1.value; var val=text2.value; box.style[name]=val; /* box.style.name=val; 点操作属性时,后面只能跟真正的属性名称,不能跟变量名; []操作属性时,里面可以放属性名称与变量名,如果放的是属性名,那就要加上引号,如果放的是变量名则不需要引号*/ } } </script> <input type="text" id="text1" value=""> <input type="text" id="text2" value=""> <input type="button" id="btn" value="按钮"> <div id="box"></div> </html>
2.属性设置
属性的设置也称之为属性赋值,与属性查询相同,具有点运算符和方括号运算符两种方法。在给对象设置属性之前,一般要先检测对象是否存在。
<input type="button" id="btn" value="按钮">
<script>
var btn = document.getElementById('btn');
btn.onclick = function () {
console.log(btn.value);
btn.value = "小按钮";//修改属性
console.log(btn.value);
}
</script>
3. 属性删除
使用delete运算符可以删除对象属性,使用delete删除数组元素时,不会改变数组长度。它只能删除自有属性,不能删除继承属性(要删除继承属性要从定义这个属性的原型上删除)。
<script>
var Person = {
sex: '男',
age: 18,
firstName: 'peng',
job: 'teacher',
array:[1,2,3],
}
//删除firstName属性
console.log(delete Person.firstName); //true
//给对象null或者是undefined并没有删除该属性
Person.und = undefined;
Person.nul = null;
console.log(Person.und,Person.nul); //undefined null
//删除数组元素时,不会改变数组的长度
console.log(Person.array);
console.log(delete Person.array[2]);//true
console.log(Person.array.length);//3
</script>
4. 属性继承
每一个对象都从原型继承属性。所有通过对象直接量创建的对象都具有同一个原型对象,并可以通过Object.prototype获得原型对象的引用
对象本身具有的属性叫自有属性,从原型对象继承而来的属性叫继承属性。
判断属性是继承还是自有的方法:in for/in hasOwnProperty() Object.keys() Object.getOwnPropertyNames()
<script>
var o={
a:1,
b:2,
}
var obj=Object.create(o);
obj.c=3;
//in操作符可以判断属性在不在这个对象上,但是无法区别自有还是继承
console.log('a' in obj);//true
console.log('c' in o);//false
//通过for/in循环可以遍历出该对象中所有可枚举属性
for(var attr in obj){
console.log(obj[attr]); //3 1 2
}
//hasOwnProperty()可以确定是自有还是继承
console.log(obj.hasOwnProperty('a'));//false
console.log(obj.hasOwnProperty('c'));//true
//Object.keys()
console.log(Object.keys(obj)); //["c"]
//obj.getOwnPropertyNames() 返回所有自有属性(包括不可枚举)
console.log(Object.getOwnPropertyNames(obj));["c"]
</script>