6.Object原型属性及方法(原型方法,实例可以调用的方法)
在Object的构造函数的原型对象中的属性和方法都可以被Object构造函数的实例所继承。
Object原型中的所具有的任何属性和方法也同样存在于其他对象中,任何对象继承自Object。
总结:每个构造函数都有一个原型对象,原型对象都包含一个指向构造函数的指针,实例都包含一个指向原型对象的内部指针。 ----《JavaScript高级程序设计》
-Object原型中常用的方法:
-constructor
保存用户创建当前对象的函数,与原型对象对应的构造函数
-hasOwnProperty(propertyName)
检查给定的属性名是否是对象的自有属性
-propertyIsEnumerable(propertyName)
检查给定的属性在当前对象实例中是否存在
-valueOf()
返回对象的字符串,数值,布尔值的表示
-toLocaleString()
返回对象的字符串表示,该字符串与执行环境的地区对应
-toString()
返回对象的字符串表示
-isPrototypeOf(object)
检查传入的对象的原型
a.isPrototypeOf(b) 如果a是b的原型,则返回true。如果b不是对象,或者a不是b的原型,则返回false。
// 使用构造函数创建实例对象 var obj = new Object() // 调用原型对象中继承的方法 console.log(obj.toString()); console.log(obj.__proto__.toString()); // 构造函数 Object console.log(Object); //[Function: Object] // 原型对象 Object.prototype console.log(Object.prototype); // {} // 原型对象中的constructor属性 原型对象中的constructor属性指向构造函数 console.log(Object.prototype.constructor); //[Function: Object] // 实例__proto__ 指向 原型对象 console.log(obj.__proto__ === Object.prototype); //true // 创建Date对象 var now = new Date(); console.log(now); // 使用原型对象中的方法 console.log(now.toString());//Mon Aug 23 2021 23:22:35 GMT+0800 (GMT+08:00) (中国标准时间) console.log(now.toLocaleString());//2021-8-23 23:22:35
7.深入理解对象-定义属性
ECMAScript中有两种属性:数据属性、访问器属性。这两种属性用于设置属性的高级属性,例如该属性是否可以配置,是否可以读写,是否可以遍历,并且可以通过setter,getter来监听数据的改变。
7.1-数据属性特性
数据属性 例如name属性
包含一个属性值的位置,这个位置可以读取和写入值。数据属性特性如下
[[Configurable]]
表示是否通过delete删除属性从而重新定义属性,能否修改属性的特性,或者能否把属性修改为访问器属性(属性直接定义在对象中,默认为true)。 当为false时,不能重新定义不能使用delete删除。
[[Enumerable]]
表示能否通过for-in循环返回属性。(属性直接定义在对象中,默认为true)
[[Writable]]
表示能否修改属性的值。(属性直接定义在对象中,默认为true)
[[Value]]
包含这个属性的数据值 name:jacky
要修改属性默认的特性,必须使用ECMAScript5的
-Object.defineProperty(属性所在的对象,属性的名字,一个描述符对象)方法
对象是由多个键/值对组成的无序的集合。对象中每个属性可以是任意类型的值。
定义对象可以使用构造函数或字面量的形式:
var obj = new Object(); obj.name = 'zhangsan'; obj.say = function () {};
除了以上添加属性的方式,还可以使用Object.defineProperty定义新属性或修改原有的属性。
-Object.defineProperty()
语法:
Object.defineProperty(obj, prop, descriptor)
参数说明:
- obj:必需。目标对象
- prop:必需。需定义或修改的属性的名字
- descriptor:必需。目标属性所拥有的特性
返回值:
传入函数的对象。即第一个参数obj;
Object.defineProperty(obj,'name',{ configurable:true, enumerable:true, writable:true, value:'terry' }) console.log(obj.name); Object.defineProperty(obj,"name",{enumerable:false}) obj.propertyIsEnumerable("name");//false
注意:当我们创建一个对象并且为对象设置一个属性的时候,该属性默认特性Configurable、Enumerable、Writable默认都为true,value为该属性的值。
-Object.defineProperties()
语法:
Object.defineProperties(obj, props)
参数说明:
- obj:必需。目标对象
- props:该对象的一个或多个键值对定义了将要为对象添加或修改的属性的具体配置
返回值:
传入函数的对象。即第一个参数obj;
var obj = new Object(); Object.defineProperties(obj, { name: { value: 'zhangsan', configurable: false, writable: true, enumerable: true }, age: { value: 18, configurable: true } }) console.log(obj.name, obj.age) // zhangsan, 18
7.2 读取属性的特性
-Object.getOwnPropertyDescriptor()
功能:
该方法返回指定对象上一个自有属性对应的属性描述符。(自有属性指的是直接赋予该对象的属性,不需要从原型链上进行查找的属性)
语法: Object.getOwnPropertyDescriptor(obj, prop)
obj: 需要查找的目标对象
prop: 目标对象内属性名称
var person = { name: '张三', age: 18 } var desc = Object.getOwnPropertyDescriptor(person, 'name'); console.log(desc) 结果如下 // { // configurable: true, // enumerable: true, // writable: true, // value: "张三" // }
-Object. getOwnPropertyDescriptors()
功能:
所指定对象的所有自身属性的描述符,如果没有任何自身属性,则返回空对象。
语法: Object.getOwnPropertyDescriptors(obj)
obj: 需要查找的目标对象
var person = { name: '张三', age: 18 } var desc = Object.getOwnPropertyDescriptors(person); console.log(desc) //{ // configurable: true, // enumerable: true, // value: '张三', // writable: true //}
访问器属性包含的四个特性:
[[Configurable]]
表示能否通过delete删除属性从而重新定义属性,能否修改属性的特性,或能否把属性修改为访问器属性, 默认为false
[[Enumerable]]
表示能否通过for-in循环返回属性,默认为false
[[Get]]
在读取属性时调用的函数,默认值为undefined
[[Set]]
在写入属性时调用的函数,默认值为undefined
这里要注意下,访问器属性不能直接定义,要通过Object.defineProperty()这个方法来定义。
/** * 访问器属性:访问器属性不包含数值,它包含的是一对getter和setter函数; * 访问器属性不能像数据属性一样直接定义,它必须使用Object.defineProperty()方法来定义 */ var book = { _year: 2020, //下划线表示是内部属性,只能通过对象的方法来读写 editor: 1 }; Object.defineProperty(book, 'year', { get: function () { return this._year; }, // 若只指定get方法,不指定set方法,那就默认该属性是只读的 set: function (newYear) { if (newYear !== this._year) { this._year = newYear this.editor ++ } } }); // 测试访问属性中的get,set方法 console.log('未修改的year:' + book.year); book.year = 2021; console.log('修改后的year:' + book.year); console.log('修改year后的editor:' + book.editor); // 问器属性可以通过Object.getOwnPropertyDescriptor()查询 console.log(Object.getOwnPropertyDescriptor(book, '_year'));
由此可以想到数据的双向绑定:
在一个对象(book)中设置一个私有属性(_year:开头下划线代表私有属性),再为这个对象设置访问器属性year(本身还未在对象中定义),当book.year进行修改时触发set函数,通过这个函数可以进行数据的操作,比如数据的判断赋值等一系列操作,从而实现数据的双向绑定。这个原理是vue的本质原理。vue是数据驱动框架,当数据发生改变的时候,视图自动更新。
-8.对象序列化
对象序列化是指将对象的状态转换为字符串,也可以反序列化,将字符串还原为对象函数。
RegExp,Error对象,undefined值不能序列化和反序列化。
JSON.stringify(obj) 将对象序列化为JSON字符串,只能序列化对象可枚举的自有属性
JSON.parse(jsonStr) 反序列化
// 将对象转换为JSON字符串 // {"name":"briup","age":12} var obj = { name:"briup", age:12 }; console.log(obj); //object类型打印的结果 {name:'briup',age:12} // 将对象转换为JSON字符串 var json = JSON.stringify(obj); console.log(json);//string类型的字符串 // 将JSON字符串转换为对象 var obj = JSON.parse(json); console.log(obj);