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>
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>