<script>
// 对象是属性的无序集合,每个属性都是一个名/值对. 属性名称是一个字符串.
// 对象种类
// 内置对象(native object)是由ECMAScript规范定义的对象或类。例如,数组、函数、日期和正则表达式都是内置对象
// 宿主对象(host object)是由JavaScript解释器所嵌入的宿主环境(比如Web浏览器)定义的, 常见的宿主对象有window, document等
// 自定义对象(user-defined object)是由运行中的JavaScript代码创建的对象。
// 对象的创建
// 对象直接量是由若干名/值对组成的,名/值对中间用冒号分隔,名/值对之间用逗号分隔,整个对象用花括号括起来。
// 属性名可以是JavaScript标识符(即变量符号,如a,b,c)也可以是字符串。
// 属性的值可以是任意类型的JavaScript表达式,表达式的值(可以是基本数据类型的值也可以是对象类型的值)就是这个属性的值。
//方法一
// let empty = {} //可以是没人任何属性的对象
// let person = {
// name : "小小",
// "name" : "小小", //加引号定义也可以 ,调用直接 person.name(不加引号,加引号就错了)
// height : "175cm",
// weight : "50",
// eating : function(){
// console.log("会吃饭");
// }
// } //还可以加函数
// console.log(person); //{name: "小小", height: "175cm", weight: "50", eating: ƒ}
// console.log(person.name); //小小
// //调用对象里面的属性 对象名.属性
// person.eating(); //会吃饭
//调用对象里面的函数。直接对象名.函数名()
// let book = {
// "main title" : "JavaScript",
// //属性名字有空格的,必须用字符串表示
// "sub - title" : "对象课程",
// //属性名字里有连字符的,必须用字符串表示
// "for" : "学员",
// //“for”是保留字,必须用引号
// author : { //该属性的值是一个对象
// name : "aiai"
// }
// }
// console.log(book); //{main title: "JavaScript", sub - title: "对象课程", for: "学员", author: {…}}
// console.log(book.author.name); //aiai
//调用对象里面的对象属性里面的属性 就一直点点点下去
//方法二
//通过关键字new,后面跟随一个函数调用。这里的函数称作构造函数,构造函数用以初始化一个新创建的对象
//JavaScript语言核心中的原始类型都包含内置构造函数
//内置对象
// let oj = new Object(); //创建一个空对象 ,和{}一样
// let date = new Date(); //创建一个表示当前时间的Date对象
// let array = new Array(); //创建一个空数组,和[]一样
//自定义对象
// function boy(){ //构造函数
// name = "", //私有属性(暂时不了解)
// //this代表实例化后的对象
// this.sex = "男",
// this.age = 25,
// this.cook = function(){
// console.log("会做饭");
// }
// }
// let gb = new boy(); //创建对象 gb是一个对象,实例化对象
// console.log(gb.sex); //男
// gb.cook(); //会做饭
//访问对象:
//方法一。点调用(.) 上诉说过了
//方法二。中括号([])
// let oj = {
// name : "xiao",
// "1" : 1,
// "name 1" : "dddd"
// }
// console.log(oj["1"]); //1
// console.log(oj["name 1"]); //dddd
// console.log(oj["name"]); //xiao
// //当然不加引号的定义也可以用[]访问
// //设置
// oj["name 1"] = "今天是星期日";
// console.log(oj["name 1"]); //今天是星期日
// oj.name = "heihei";
// console.log(oj.name); //heihei
//对象常用操作
//删除对象的属性
//delete运算符可以删除对象的属性
// let oj = {
// a : "1",
// b : { x : 1}
// }
// let ob = oj.b;
// console.log(oj.b); //{x: 1}
// delete oj.b;
// console.log(oj.b); //undefined
// console.log(ob); //{x: 1}
//delete只是断开属性和宿主对象的联系,而不会去操作内存中对象的属性的值的存在与否
// 判断某个属性是否存在于某个对象中
// 可以通过in运算符、hasOwnProperty() 方法
// let oj = {
// a : "1",
// b : { x : 1}
// }
// console.log( "a" in oj); //true
// console.log("c" in oj); //false
// console.log( oj.hasOwnProperty("a")); //true
// console.log( oj.hasOwnProperty("c")); //false
//枚举对象属性
//除了检测对象的属性是否存在,我们还会经常遍历对象的属性, 通常使用for/in循环遍历
// for/in循环可以在循环体中遍历对象中所有可枚举的属性(包括自有属性和继承的属性)
// 对象继承的内置方法不可枚举的,但在代码中给对象添加的属性都是可枚举的
// for( o in oj){
// console.log(o); //a b
// }
// console.log(o.propertyIsEnumerable("toString")); //false
//在JavaScript中对象的属性有两种, 分别是数据属性和访问器属性.
// //数据属性包含一个数据值的位置。在这个位置可以读取和写入值。数据属性有4 个描述其行为的特性
// 程序员无法访问到的
// [[Configurable]]:表示能否通过delete 删除属性从而重新定义属性,能否修改属性的特性,或者能否把属性修改为访问器属性。像前面例子中那样直接在对象上定义的属性,它们的这个特性默认值为true。
// [[Enumerable]]:表示能否通过for-in 循环返回属性。像前面例子中那样直接在对象上定义的属性,它们的这个特性默认值为true。
// [[Writable]]:表示能否修改属性的值。像前面例子中那样直接在对象上定义的属性,它们的这个特性默认值为true。
// [[Value]]:包含这个属性的数据值。读取属性值的时候,从这个位置读;写入属性值的时候,把新值保存在这个位置。这个特性的默认值为undefined
//访问器属性 允许用户在赋值或取值都经过预先设定的函数,从而实现内部属性的那一种特效结果
//get / set
//获取对象属性的特性Object.getOwnPropertyDescriptor()
// let oj = {
// a : "1",
// b : { x : 1}
// }
// let c = Object.getOwnPropertyDescriptor(oj,"a");
// console.log(c); //{value: "1", writable: true, enumerable: true, configurable: true}
// //设置对象属性的特性Object.defineProperty()
// //传入要修改的对象、要创建或修改的属性的名称以及属性描述符对象:
// Object.defineProperty(oj, "a" ,{
// writable:false
// })
// oj.a = "333";
// let cg = Object.getOwnPropertyDescriptor(oj,"a");
// console.log(cg); //{value: "1", writable: false, enumerable: true, configurable: true}
// console.log(oj.a); //1
</script>