概述:
Object类是所有类的父类,也就是说所有对象都默认继承Object类,那么对应的Object的方法所有的对象都可以使用。主要学习的object的相关方法是提供给其他对象使用的。
Object相关属性及方法
Object的方法主要分为原型方法(实例)和静态方法、相关属性对应的实例拥有的属性(实例属性)
相关属性
__proto__表示对应对象的原型指定当前构造函数的原型prototype
console.log({}.__proto__)//指向对应的Object的原型prototype
constructor表示对象的构造函数
console.log({}.constructor)
原型方法
hasOwnProperty(判断本身是否具备这个属性 不包含原型上的)
// 原型添加的属性
Object.prototype.age =18
// 本身的对象
let obj = {
name : 'joe'
}
obj.sex = '男'
// console.log(obj.name)//18 原型上的属性
console.log(obj.name) // 本身的属性
// hasOwnProperty 判断对象本身是否具有属性 不包含原型上的属性
// 传入属性名
console.log(obj.hasOwnProperty('name')) //true
console.log(obj.hasOwnProperty('age')) //false
console.log(obj.hasOwnProperty('sex')) //true
isPrototypeof 判断当前对象是否存在原型链上
class Person{
constructor(){
this.name = 'tom'
}
}
class Child extends Person{
constructor(){
super()
Child.age = 20
}
}
let child = new Child()
let person = new Person()
console.log(child.isPrototypeOf(Person)) // false
console.log(person.isPrototypeOf(child)) // false
// 判断是否在原型链上 出入的是对应的对象
console.log(Person.prototype.isPrototypeOf(child)) // true 对应的Person原型是否在child的原型链上
// 将对应的child原型进行赋值
child.__proto__ = person
//isPrototypeOf 传入的是对应的查找原型链的对象
console.log(Person.isPrototypeOf(child)); //false
propertyIsEnumerable 判断属性是否枚举(是否可以被for in 遍历)
class Animal{
constructor(){
this.name = 'dog'
this.run =()=>{}
}
// 不能被枚举
eat(){
}
}
let animal = new Animal()
animal.age = 22 //默认的赋值对应的属性可以被遍历
for(var key in animal){
console.log(key) // name run
}
// 检索是否可以枚举(for in 只能遍历可以被枚举的属性)
console.log(animal.propertyIsEnumerable('run')) // true
console.log(animal.propertyIsEnumerable('name')) // true
console.log(animal.propertyIsEnumerable('age')) // true
console.log(animal.propertyIsEnumerable('eat')) // false
toString 将对象转为字符串 toLocalString 将对象转为本地格式字符串
valueOf 得到本身的值
废弃的四个方法
- __defineGetter__ 定义getter函数
- __defineSetter__ 定义setter函数
- __lookUpGetter__返回getter函数
- __lookUpSetter__ 返回setter函数
// 废弃的四个方法
let obj1 = {
name : 'jessi',
age:26
}
let _obj ={
name : 'jessi',
age:26
}
//__defineGetter__ __defineSetter__ 定义getter setter 方法
// 传递的属性名 和对应的处理函数
obj1.__defineGetter__("name",()=>{
console.log('执行了');
return _obj.name //getter不允许调用自身
})
obj1.__defineSetter__('age',(value)=>{
_obj.age = value
// obj.age = value 报错 栈溢出
})
console.log(obj1.name) //调用getter 获取getter中的返回值
obj1.age = 30 //调用setter方法
// __lookupGetter__ __lookupSetter__ 返回对应的getter方法和setter方法
console.log(obj1.__lookupGetter__('name')); //false
console.log(obj1.__lookupSetter__('age')); //true
静态方法
Object.assign 将传入的对象的内容填入第一个传入的对象内容内 返回的是第一个对象
// 里面可以传入任意对象 将对应的后面的参数内容填入到第一个对象中 返回第一个对象
let first={
name:'joe',
likes:['睡觉']
}
let object = Object.assign(first,{
age:'22'
},{
sex:'未知'
})
console.log(object) // {name:'joe',age:'22',sex:'未知'}
console.log(first == object) //true
console.log(first)
//object.assign 可以完成对象的浅拷贝(拷贝第一层值 深层拷贝地址 产生新的对象)
let copyObj = Object.assign({},first) //false
//第二层拷贝地址 copyObj的likes对应的地址 和first 的likes 地址是一样的
console.log(copyObj.likes == first.likes)//true
Object.create 创建一个对象
// 根据传入的对象来创建对应的内容
let first = {
name :'dot'
}
// create是将对应的传入的对象放入创建对象的原型上
let newObj = Object.create(first) //根据传入的first来创建一个新的对象
console.log(newObj)
let obj =create(first)
console.log(obj)
// 简单实现一下object的create方法
function create(obj){
// 创建一个新对象
let newObj = {}
// 将传入的对象放入新对象的原型上
newObj.__proto__ = obj
// 返回这个新对象
return newObj
}
Object.keys 返回对象所有的key组成的数组
Object.values 返回对象所有的value组成的数组
Object.entries 返回对象所有的键值对组成的数组
let ibj = {
name :'top',
age:24
}
class Person{
constructor(){
}
// 不可枚举的
eat(){
}
}
// 原型上的属性
Person.prototype.age = 19
// 返回的都是数组
console.log(Object.keys(obj)) //所有key的数组
console.log(Object.values(obj)) //所有value的数组
console.log(Object.entries(obj)) //所有键值对
//Object.keys不包含不可枚举的属性 也不包含原型上的属性
let person = new Person()
console.log(Object.keys(person))
// for in 不包含不可枚举的属性 包含原型上的属性
for(var key in person){
console.log(key)
}
Object.is 判断两个对象是否一致
// Object.is 判断两个对象是否一致
let first = {}
let last = {}
console.log(Object.id(first, last)) // false
Object.getPrototypeOf 获取原型
Object.setPrototypeOf 设置原型
// Object.getPrototypeOf获取原型
// Object.setPrototypeOf 设置原型
function Person() { }
Person.prototype.age = 19
let person = new Person()
// 获取原型Object.getPrototypeOf
console.log(Object.getPrototypeOf(person))//获取Person的原型对象 相当于获取__proto__
// 设置原型 相当于给__proto__进行赋值 setPrototypeof
let obj = {
name: 'kio'
}
Object.setPrototypeOf(person, obj) //将obj加入到person的原型
console.log(obj.isPrototyprOf(person)) //true
console.log(person)
对象相关操作限制的方法
不可扩展 不能进行内容添加preventExtensions (isExtensible 判断是否可扩展 )
密封 只能查询和修改 其他操作不能允许seal(isSealed 判读是否密封)
冻结 只能查询 freeze(isFrozen判断是否冻结)
冻结必定密封和不可扩展 密封必定不可扩展
// 冻结必定密封和不可扩展 密封必定不可扩展
// 查询都能做 不然对应的对象创建并没有意义
let obj = {
name:'koko'
}
// 不可扩展 返回当前的对象
Object.preventExtensions(obj)
// 检测是否可以扩展
console.log(Object.isExtensible(obj)) //false
// 添加新的属性
obj.age = 20 //无效
obj.name = 'top' // 改
console.log('name' in obj) //查询
delete obj.name //删除
console.log(obj)
// 密封
let obj1 ={
name:'haha'
}
// 使用对象密封
Object.seal(obj1)
// 密封会导致不可扩展
console.log(Object.isExtensible(obj1)) // false
//判断是否密封
console.log(Object.isSealed(obj1)) //true
obj.age = 20 //无效
obj.name = 'top' // 改
console.log('name' in obj) //查询
delete obj.name //删除 无效
console.log(obj)
// 冻结 只能查询
let obj2 = {
name:'vivi'
}
// 冻结对象 只能做查询操作
Object.freeze(obj2)
// 判断是否冻结
console.log(Object.isFrozen(obj2))//true
// 判断是否密封
console.log(Object.isSealed(obj2)) //true
obj.age = 20 //无效
obj.name = 'top' // 改 无效
console.log('name' in obj) //查询
delete obj.name //删除 无效
console.log(obj)
属性对象(descriptor 对象)
属性属性
configable 是否可以删除
enumerable 是否可以枚举
value 值
writable 是否可以修改
Object.defineProperty 用于定义对象的属性(vue2 的底层实现)
实现数据驱动(双向数据绑定)
let obj = {}
// 传入对象 传入属性 传入属性对象
Object.defineProperty(obj, 'name', {
configurable: true,
enumerable: true,
value: 'tom',
writable: true
})
console.log(obj) //{name:tom}
obj.name = 'vivi' //无效 writable为false
for (var key in obj) {
console.log(key) //name不会打印 enumerable为false
}
delete obj.name //无效 configurable 为false
console.log(obj)
// 传入访问器属性对象 进行属性定义
let _obj = {} //借助一个新的对象来进行操作
Object.defineProperty(obj, 'age', {
configurable: true,
enumerable: true,
get() {
console.log('访问了get')
return _obj.age
//return obj.age 会造成栈溢出
},
set(value) {
console.log('访问了set')
_obj.age = value
}
})
obj.age = 22 //访问了set
console.log(obj.age) //访问了get
Object.defineProperties 用于定义对象的多个属性
let obj = {}
// 传入对象 传入属性 传入属性对象
let _obj = {} //借助一个新的对象来进行操作
Object.defineProperty(obj, 'age', {
name: {
configurable: true,
enumerable: true,
value:'tob',
writable:true
},age:{
configurable: true,
enumerable: true,
get() {
console.log('访问了get')
return _obj.age
//return obj.age 会造成栈溢出
},
set(value) {
console.log('访问了set')
_obj.age = value
}
}
})
console.log(obj)
面试题
查看属性的相关方法
for in 只能遍历可枚举的属性(可以遍历原型上的 不可以遍历symbol)
Object.keys 只能遍历本身的(不可以遍历原型上的 也不能遍历不可枚举的 不可以遍历symbol)
Object.getOwnPropertyNames(可以遍历原型上不可枚举的 不可以遍历symbol)