JavaScript统计数据处理(2) - 对象
在浏览器中运用JavaScript技术处理统计数据具有最佳的推广传播效果
对象(Object)在编程语言中是一个比较抽象、牵涉内容非常多的概念。对于JavaScript来说,对象可以是一个变量、一个数据结构、或是一个函数。对象既表示客观世界问题空间中的某个具体的事物,又表示软件系统解空间中的基本元素。
在软件系统中,对象具有唯一的标识符,对象包括属性(Properties)和方法(Methods)。属性就是需要记忆的信息,方法就是对象能够提供的服务。
JavaScript提供多个内建对象,比如String、Date、Array、Math等等。对象是带有属性和方法的特殊数据类型,JavaScript的内建对象需要在学习JavaScript语法知识时加以掌握。
本文介绍利用花括弧“{}”对象建立和操作统计数据结构,并结合上文介绍的数组知识进一步学习JSON数据结构。
1、创建对象及对象属性
[返回]console.clear(); var obj1 = { name: "Arvin", //nameww为属性名称、Arvin为属性值 gender: "Female" }; console.log(obj1); //创建嵌套的对象obj2 var obj2 = { name: "Arvin", contact: { qq: "1465712345", tel: "1465712311", mail: "1465712311@163.com" } }; console.log(obj2); //同时嵌套数组和对象obj3 var obj3 = { name: "Arvin", contact: { qq: "1465712345", tel: "1465712311", mail: "1465712311@163.com" }, absent: [12,15,24] }; console.log(obj3); //数组元素也可以是对象 var arr = [ 20, 45, obj = {name: "Arvin", gender: "Female"}, val = [1,2,3,4,5] ]; console.log(arr);
注:这里只涉及对象的属性,关于对象的方法在学习JS函数后再进一步介绍
在创建对象的代码中可以看到JS对象和数组的运用非常灵活,可以根据统计数据结构的特点任意嵌套创建对象和数组(数组也是JS的一个内建对象)。对象和数组嵌套结构可以描述我们在实践工作中遇到的各种数据,所有的数据最终都可以分解成三种类型:
- 第一种类型是标量(scalar):指一个单独的字符串(string)或数字(numbers);
- 第二种类型是序列(sequence):指由相关的数据按照一定顺序并列在一起,又叫做数组(array);
- 第三种类型是映射(mapping):也就是一个名/值对(Name/value),即数据有一个名称,还有一个与之相对应的值。
数据结构的构成竟是如此的简单!在编程语言中,只要有了数组(array)和对象(object)就能够描述、储存一切数据了。
21世纪初,Douglas Crockford尝试寻找一种简便的数据交换格式,能够在服务器之间交换数据。当时通用的数据交换语言是XML(Extensible Markup Language,可扩展标记语言),但是Douglas Crockford觉得XML的生成和解析都太麻烦,所以他提出了一种简化格式,也就是JSON。
JSON采用完全独立于语言的文本格式,但是也使用了类似于C语言家族的习惯(包括C、C++、C#、Java、JavaScript、Perl、Python等)。这些特性使JSON成为理想的数据交换语言。易于人阅读和编写,同时也易于机器解析和生成(网络传输速率)。
Json的规格比较简单,只用一个页面几百个字就能说清楚,而且Douglas Crockford声称这个规格永远不必升级,因为该规定的都规定了。
JSON数据格式规则:
- 并列的数据之间用逗号(", ")分隔;
- 映射用冒号(": ")表示;
- 并列数据的集合(数组)用方括号("[]")表示;
- 映射的集合(对象)用花括号("{}")表示。
上面四条规则,就是Json格式的所有内容,就是我们前面提到的对象和数组嵌套结构。
2、JSON属性引用和修改
[返回]console.clear(); var obj = { name: "Arvin", contact: { qq: "1465712345", tel: "1465712311", mail: "1465712311@163.com" }, absent: [12,15,24] }; var temp = obj.name; //获得属性值Arvin temp = obj.contact.tel; //1465712311 temp = obj.absent[1]; //15 console.log(temp); obj.name = "Carolyn"; //属性修改 obj.absent[1] = 99; console.log(obj); var obj1 = { "name": "Arvin", "age": 18 }; console.log(obj1.name);
注:JSON对象属性名称可以加引号,也可以不加引号;JSON对象属性值为字符时必须加引号,为数值时不加引号
3、JSON属性和对象添加
[返回]console.clear(); //建立一个简单对象 var obj = { name: "Arvin" }; obj.lastname = "Joe"; //添加属性名/值对 obj.contact = {}; //添加对象 obj.contact.qq = "1465712345"; //为新对象添加属性名/值对 obj.contact.tel = "1465712311"; obj.contact.mail = "1465712311@163.com"; obj.absent = [12,15,24]; //添加属性名/数组 console.log(obj);
4、JSON属性和对象删除
[返回]console.clear(); var obj = { name: "Arvin", contact: { qq: "1465712345", tel: "1465712311", mail: "1465712311@163.com" }, absent: [12,15,24,67] }; delete obj.name; //删除name属性 delete obj.contact.mail; delete obj.contact; //对象删除 //删除absent属性数组最后一个元素(此时下标值删除,但数组长度不变) delete obj.absent[3]; //彻底删除absent属性数组最后一个元素(此时下标值删除,数组长度变化) obj.absent.splice(3,1); console.log(obj);
5、JSON对象和JSON字符互相转换
[返回]JSON是简便、最广泛使用的数据交换格式,也是统计学数据结构的最佳载体。运用JSON对象描述统计数据非常JS编程进行各种统计运算,当要存储数据时,需要将JSON对象转换为字符;而处理数据时,又需要读取JSON字符后转换为对象。
console.clear(); JSON字符转对象 var jsonStr = '[{"CityId":18,"CityName":"西安"},{"CityId":53,"CityName":"广州"}]'; var jsonObj = eval("("+jsonStr+")"); //使用eval函数将JSON字符转换为对象 console.log(jsonObj[0]["CityName"]); var jsonObj = JSON.parse(jsonStr); //使用JSON.parse()方法进行转换 console.log(jsonObj[1]["CityName"]); var jsonObj = { "CityId":"18", "CityName":"西安2" }; //JSON对象转字符 var jsonStr = JSON.stringify(jsonObj); console.log(jsonStr);
注:使用JSON.parse()方法和JSON.stringify方法是,JSON对象属性名需要加引号
6、JS对象的属性特性(*)
[返回]ECMAScript对象中目前存在的属性描述符主要有两种,数据描述符(数据属性)和存取描述符(访问器属性),数据描述符是一个拥有可写或不可写值的属性。存取描述符是由一对 getter-setter 函数功能来描述的属性。
- JS对象数据描述符(数据属性):
- Configurable(可配置属性): 表示能否通过delete删除此属性,能否修改属性的特性,默认值为true
- Enumerable(可枚举属性): 表示该属性是否可枚举,即是否通过for-in循环或Object.keys()返回属性,默认值为true
- Writable(可读属性): 能否修改属性的值,默认值为true
- Value(数值属性): 该属性对应的值,默认为undefined
- JS对象存取描述符(访问器属性):
- Configurable(可配置属性): 和数据属性的Configurable一样,表示能否通过delete删除此属性,能否修改属性的特性,或能否修改把属性修改为访问器属性,默认值为true
- Enumerable(可枚举属性): 和数据属性的Configurable一样,表示该属性是否可枚举,即是否通过for-in循环或Object.keys()返回属性,默认值为true
- Get(获得): 一个给属性提供 getter 的方法(访问对象属性时调用的函数,返回值就是当前属性的值),如果没有 getter 则为 undefined。该方法返回值被用作属性值。默认为 undefined
- Value(设置): 一个给属性提供 setter 的方法(给对象属性设置值时调用的函数),如果没有 setter 则为 undefined。该方法将接受唯一参数,并将该参数的新值分配给该属性。默认为 undefined
I、属性测试
console.clear(); var obj = { name: "Arvin", contact: { qq: "1465712345", tel: "1465712311", mail: "1465712311@163.com" }, absent: [12,15,24,67] }; console.log(obj.hasOwnProperty("name")); console.log(obj.contact.hasOwnProperty("qq")); console.log(obj.hasOwnProperty("absent"));
II、创建/修改/获取属性的方法
a. Object.defineProperty()方法会直接在一个对象上定义一个新属性,或者修改一个对象的现有属性,并返回这个对象。如果不指定configurable, writable, enumerable,则这些属性默认值为false,如果不指定value, get, set,则这些属性默认值为undefined
console.clear(); var obj = new Object(); // Object.defineProperty(obj, 'name', { configurable: false, writable: true, enumerable: true, value: '张三' }) console.log(obj.name) //张三
b. Object.defineProperties()方法直接在一个对象上定义一个或多个新的属性或修改现有属性,并返回该对象。
console.clear(); var obj = {}; Object.defineProperties(obj, { name: { value: '张三', configurable: false, writable: true, enumerable: true }, age: { value: 18, configurable: true } }) console.log(obj.name, obj.age) // 张三, 18
c. Object.getOwnPropertyDescriptor()方法返回指定对象上一个自有属性对应的属性描述符。
console.clear(); var person = { name: '张三', age: 18 } var desc = Object.getOwnPropertyDescriptor(person, 'name'); console.log(desc);
d. Object. getOwnPropertyDescriptors()所指定对象的所有自身属性的描述符。
console.clear(); var person = { name: '张三', age: 18 } var desc = Object.getOwnPropertyDescriptors(person); console.log(desc);
e. Configurable(可配置属性):如果设置configrubale属性为false,则不可使用delete操作符, 修改所有内部属性值会抛出错误。
console.clear(); var person = {}; Object.defineProperty(person, 'name', { configurable: false, value: 'John' }) ; delete person.name // 严格模式下抛出错误 console.log(person.name) // 'John' 没有删除 Object.defineProperty(person, 'name', { configurable: true //报错 }); Object.defineProperty(person, 'name', { enumerable: 2 //报错 }); Object.defineProperty(person, 'name', { writable: true //报错 }); Object.defineProperty(person, 'name', { value: 2 //报错 });
f. Writable(可读属性):当writable为false(并且configrubale为true),value可以通过defineeProperty修改, 但不能直接赋值修改。
console.clear(); var obj = {} Object.defineProperty(obj, 'a', { configurable: true, enumerable: false, writable: false, value: 1 }); obj.a=2; var d = Object.getOwnPropertyDescriptor(obj, 'a') console.log(d); // 结果如下 // { // value: 1, // 没有做出修改 // writable: false, // enumerable: true, // configurable: false // }
g. Enumerable(可枚举属性):当Enumerable为false(并且configrubale为true),该属性不能被枚举显示。
console.clear(); var obj = {} Object.defineProperty(obj, 'a', { configurable: true, enumerable: false, writable: false, value: 1 }); obj.a=2; var d = Object.getOwnPropertyDescriptor(obj, 'a') console.log(d); // 结果如下 // { // value: 1, // 没有做出修改 // writable: false, // enumerable: true, // configurable: false // }
III、添加存取描述符属性
get/set(读/写)通过get/set函数为对象指定属性设置读写功能。
console.clear(); var obj = {}; var aValue; //如果不初始化变量, 不给下面的a属性设置值,直接读取会报错aValue is not defined var b; Object.defineProperty(obj, 'a', { configurable : true, enumerable : true, get: function() { return aValue }, set: function(newValue) { aValue = newValue; b = newValue + 1 } }) console.log(b) // undefined console.log(obj.a) // undefined, 当读取属性值时,调用get方法,返回undefined obj.a = 2; // 当设置属性值时,调用set方法,aValue为2 console.log(obj.a) // 2 读取属性值,调用get方法,此时aValue为2 console.log(b) // 3 再给obj.a赋值时,执行set方法,b的值被修改为2 console.clear(); //obj的y属性值只读 var obj = { x:1, get y(){return x;}, //set y(value){x = value;} }; obj.y=10 //修改无效 console.log(obj); //obj的y属性值可读写 var obj = { x:1, get y(){return x;}, set y(value){x = value;} }; obj.y=10 //修改有效 console.log(obj);
本文只介绍了JS对象属性的基本用法,当我们循序学完函数、方法等知识后,再进一步介绍JS对象的方法及面向对象编程。标记(*)号部分初学者可以忽略。
提示:本页中JS脚本代码可复制粘贴到JS代码运行窗口调试体验; 文本编辑快捷键:Ctrl+A - 全选;Ctrl+C - 复制; Ctrl+X - 剪切;Ctrl+V - 粘贴
©哈尔滨商业大学 银河统计工作室
银河统计工作室成员由在校统计、计算机部分师生和企业数据数据分析师组成,维护和开发银河统计网和银河统计博客(技术文档)。专注于数据挖掘技术研究和运用,探索统计学、应用数学和IT技术有机结合,尝试大数据条件下新型统计学教学模式。