对象

对象的使用

     在对象中如果使用字面量定义对象{}只能通过点语法赋值,点语法只是字符串,表达式不能通过点语法赋值
      var obj={
            aa:‘true’,
            bb:'ccc'
      }
      key值相同  后一个会把前一个覆盖
      obj['b'+'b']='dsdsd' 
      console.log(obj)  {aa:'true',bb:'dsdsd'} 
      
     

## Es6  可以使用表达式作为key值   表达式可以为方法名
     var obj={
           ['b'+'b']:true,
           ['a'](){return 1}
     }
     obj['b'+'b']='dsdsd'
     console.log(obj)    {bb:'dsdsd'}
     
     obj={
            a:'1',
            b:2
     }
     obj={
           a:'dasdsad',
           b:'ssss'
     }
     通过字面量的方式    新定义一个对象下面会把上面覆盖
     console.log(obj)       {a:'dasdsad',b:'ssss'} 
     function Dian(){
             obj={
                 a:'11111'   
             }
             obj.a='aaaa'
             obj['b']=2222
             点语法  下面会把上面覆盖   只是对值的覆盖  用的还是同一堆内存空间
             console.log(obj)    {a:'aaaa',b:2222}
     }
     
    
   属性名表达式   与简单表示法  不能同时使用
       const   foo='bar'
       const   bar='baz'
       const ob={a:'1'}
       //const baz={[foo]}  报错
       const baz={[foo]:bar}
       console.log(baz)     //{bar:'baz'}
       key 值如果是一个对象会被转化成字符串
       const oc={[ob]:'1111'}
       console.log(oc)  //{[object  object]:'1111'}
     对象的可枚举性
         对象的每一个属性,都有一个描述对象(Descripter),用来控制该属性的行为
         enumerable 属性称为可没举性   如果该属性为false 某些操作会忽略当前属性
         for in    只遍历自身和继承的可枚举属性
         Object.keys()   返回自身所有的可枚举属性
         JSON.stringify
         Object.assion()   忽略只拷贝对象自身的可枚举属性

         obj={
              name:'1111'
          }
          console.log(Object.getOwnPropertyDescriptor(obj,'name'))  
          // configurable:true  enumerable:true   value:'1111'   writable:true
          对象的toString 就是改变可枚举属性  让for in  无法遍历到
          console.log(Object.getOwnPropertyDescriptor(obj.toString,'name'))  
          // configurable:true  enumerable:false  value:'toString'   writable:false
          Es6 规定 有Class 的都是不可枚举的
          console.log(Object.getOwnPropertyDescriptor(class{foo(){}}.prototype,'foo'))
           // configurable:true  enumerable:false  value:'foo ()'   writable:true
           
 属性的遍历
      遍历的都是自身属性   继承的属性无法遍历
1.      for(const  i in Object.getOwnPropertyDescriptor(obj.toString,'name')){
            console.log(i,Object.getOwnPropertyDescriptor(obj.toString,'name')[i])
            //   value   toString
            //  writable  false
            //enumerable   false
            //configurable   true
       }
       //Object.keys(obj)  返回一个数组不含Symbol   属性
2.       Object.keys(Object.getOwnPropertyDescriptor(obj.toString,'name'))
       //[value,enumerable,...]
       Object.getOwnPropertyNames   返回一个数组   不含Symbol 属性
       console.log(Object.getOwnPropertyNames(Object.getOwnPropertyDescriptor(obj,'name')))
       Object.getOwnPropertySymbols(obj)   返回一个数组    包含自身所有Symbol 属性键名
       Reflect.ownKey(obj)   返回一个数组 包含自身所有键名   不管键名是 Symbol 还是字符串  还是是否可枚举
遍历对象遵循的次序,首先遍历所有的数值键  ,按照数值升序排序,其次遍历所有的字符串键  ,
按照加入的时间升序排序,最后遍历所有的Symbol 键  按照加入的时间升序排序
     Super 关键字
     setPrototypeOf()  给当前对象设置原型对象
     super 指向对象的原型对象
     super  只能写在方法中  只有对象方法的简写  才可以让javaScript 引擎确认定义的是对象的方法  
     const pro={
          foo:‘222’,
          x:2,
          xx(){
             //当前this还是obj
              return this.x
          }
     }
     obj={
        foo:'hello',
        x:1,
        find(){
            //super.foo  等同于  Object.getPrototypeof(this).foo(属性) 或者  Object.getPrototypeof(this).foo.call(this)  方法
            super  查找的是原型上的属性
            return super.foo
       }
    }
    //设置当前对象的原型对象
    Object.setPrototypeOf(obj,pro)
    //不设置原型对象super  就无法找到  this 查找的是当前元素的属性
    console.log(obj.find())   //222
   创建对象的方法
   Object.create()  参数只能是一个null 或者  对象  如果是null 没有原型链  对象有
   里面可以创建两个参数  第一个是对象的原型  propertiesObject  
   第二个参数是   属性描述符  属性描述符 和 Object.defineProperties()  的第二个参数一样  参数对象不能为undefined
   也就是说自身必须拥有可枚举属性才有效
   字面量创建对象和构造函数创建对象
   console.log({},new Object(),Object.create({})) 
   console.log({x:1}.length,new Object(1).length,Object.create({}).length)  undefined  undefined  undefined
   var  proo={
           a:1
   }
   var obj={
           x:1
   }
   Object.setPrototypeOf(obj,proo)
   console.log(Object.create(proo,Object.getOwnPropertyDescriptors({x:1})))   {x:1}
   拷贝属于深拷贝  新创建了一块堆内存空间  虽然值相同但是内存不同
   console.log(Object.create(proo,Object.getOwnPropertyDescriptors({x:1}))==obj) false  
   console.log(obj.__proto__===Object.create(proo).__proto__)  true
Javascript   深拷贝和浅拷贝
      深拷贝:简单来说就是旧对象 改变  ,新对象保持不变    浅拷贝  :   就是新对象发生改变
      基本数据类型:名字和值都存储在栈内存空间内
      深拷贝就是针对 引用数据类型   堆内存存储数据    名字地址  存储在栈内存中
      栈内存提供一个引用的地址  指向  堆内存中的  存储的值
      var arr=[1,2]  var arr1=arr   arr[0]='111'   console.log(arr1)   ['111',2]
      arr1 只复制了arr 的地址  他们还在共有一块堆内存空间  这就是浅拷贝
      深拷贝就是在堆内存中重新开辟一块空间  用来保存arr1的值,他们之间相互不干扰
      var obj={
         a:1,
         b:{
              c:'222'
           }
       }
       var obj1=Object.assign({},obj)
       obj.a='11'
       obj.b.c='ccccc'
       Object.assign()   第一层深拷贝   第二层浅拷贝
       console.log(obj1)   {a:1,b:{c:'cccc'}}
       实现深拷贝的方法就是  将值取出来  重新赋值给新创建的对象
       JSON.stringify()  JSON.parse()  无法实现对象中方法的深拷贝
       
    结构赋值
    解构赋值   将一个对象的值拷贝到另一个对象上
    结构赋值  要求等号右边是一个对象  如果是null 和  undefined  就会报错
    结构赋值的拷贝是浅拷贝,如果一个键是复合类型的值(数组,对象,函数) 那么结构赋值是这个值的引用
    obj={a:{b:1}}
    let  {...x}=obj
    x.a.b   x就相当于Obj这个值
    扩展运算符的解构赋值,只是解构自身属性  不能赋值继承自原型对象的属性  只能复制自身
    扩展运算符后面必须是一个变量名  不能是一个结构赋值表达式
     let o1={a:1}
     let o2={b:1}
     o2.__proto_=o1
     let  {...o3}=02
     console.log(o3.a)//  undefined     扩展运算符无法拷贝原型上的东西
     console.log(o3.b)  //1
u     创建对象
      let oo=Object.create(null)  //创建的对象没有原型
      let oq=Object.create({x:1,zz:'aaaa'})
      oq.z='1111'
      console.log(oq)  //{z:'1111'}   z:'1111'     __proto__  :x:1   ,zz:'aaaa'
      let {x,z,...newObj}=oq
      console.log(x,z,newObj)  //1    1111   {}  扩展运算符无法解析原型上的值
    扩展运算符  后面如果不是对象  会自动转化成对象 正数会自动转化成数值的包装对象Number(1)   
    由于对象没有自身属性  所以会返回一个空对象
    console.log(...1) {}
    console.log(Object.assign({b:2},{x:1}))  {b:2,x:1}
    其他基本数据类型都是如此,字符串会转化成类似于数组的对象
    扩展运算符和Object.assign({},obj)  一样  都是只拷贝单层数据  对复合数据  第二层 和原型上 的数据无法拷贝
    Object.assign()  和  扩展运算符都是只拷贝  对象实例的属性  无法拷贝原型对象的属性  
    getOwnPropertyDescriptor和getOwnPropertyDescriptors的区别?
    getOwnPropertyDescriptor:返回某个对象属性的描述对象
    getOwnPropertyDescriptors:返回指定对象的所有自身属性  (非继承属性) 的描述对象
    实现对对象继承属性的拷贝
       let o1={a:1}
       let o2={b:1}
       o2.__proto__=o1
       非浏览器下不一定部署 
    const clone1={
        __proto__:Object.getPrototypeOf(o2),
        ...o2
   }
   // 实现对 o2 原型继承的克隆
   console.log(clone1)   b:1  __proto__  a:1
   const clone2=Object.assign(Object.create(Object.getPrototypeOf(o2)),o2)
   console.log(clone2)   b:1  __proto__  a:1
   const clone3=Object.create(
      Object.getPrototypeOf(o2),
      Object.getOwnPropertyDescriptors(o2)
  )
     console.log(clone3)   b:1  __proto__  a:1
      同一个对象如果key相同  后面会将前面覆盖
      const ll={x:1,y:2}
      console.log({...ll,x:sss,y:kkk})    {x:sss,y:kkk}
      console.log({x:sss,y:kkk,...ll})    {x:1,y:2}
判断对象中是否包含某个属性
JavaScript  的继承属性  和  自身属性
function aa(){this.name="111"  自身属性,在this上定义的都是当前对象的自身属性}
判断 属性是否是自身属性和继承属性
  其中in   判断包含自身属性和继承属性   
hasOwnProperty 判断是否为自身属性,无法判断原型上的属性
propertylsEnumerable()  是  hasOwnProperty  的增强版

obj={x:1}
var obj1={x:undefined,y:null}
当前对象跟undefined  进行比较  若为true  表示当前对象有这个属性   
为false 代表当前对象没有这个属性   toString 是从当前Object 原型上继承的属性
console.log(obj.x !==undefined,obj.y !==undefined,obj.toString !==undefined) true   false true

in  可以判断值为undefined 的时候属性是否存在
console.log('x' in obj,'y' in obj 'toString' in obj)   true   false true
console.log(obj1.x !==undefined ,obj1.y !== undefined,'x' in obj1  ,'y' in obj1)  false true true true

判断继承属性
pro={
    ss:'2222'
}
obj={
    aa:'1111'
}
Object.setPrototypeof(obj,pro)
console.log(Object.getPrototypeof(obj))    {ss:'2222'}   获取原型上的属性
console.log('ss' in obj,obj.hasOwnProperty('aa'),obj.hasOwnProperty('ss'))   true  true   false

     判断属性类型  
       typeof 
       instanceof  :判断一个构造函数的Prototype属性所指向的对象,是否存在另一个要检测对象的原型链上,判断一个实例是否属于原型链上的属性
       isPrototypeof  : 判断实例是否指向某个对象的原型对象   判断这个实例是否是当前对象的实例
      
        console.log(typeof null,typeof [],typeof window ,typeof global)  object  object  object   undefined  
        console.log([] instanceof Array,[] instanceof object)   true true
        funcrion a(){}  function b(){}   const c=new a()
        console.log(a.prototype.isPrototypeof(c),Object.prototype.isPrototypeof(c),b.prototype.isPrototypeof(c))  true true false
      const  定义常量
      const 定义的基本类型都是无法更改的
      栈内存空间    线性排列的每个小单元大小基本相等,已知大小,范围有上限,
      null 为空  类型为Object  存储在栈内存中
      对于基本数据类型  值就是指针  对于引用数据类型  常量就是指针
      const  定义的对象  指向堆内存的地址指针是不可变的   堆内存的数据是可变的
      const let  初始化一个变量首先要遍历当前的内存栈  有重名的返回错误
      new 初始化之后返回一个对象  
      值类型  和  引用类型  就是栈变量和堆变量
      const kk={o:1}
      内存分配和垃圾回收
      一般来说:栈内存是有序回收,容量小 ,分配效率高
      堆内存需要重新分配存储区域,之后就把指针存储在堆内存中,效率相对低一些,
      垃圾回收方面:栈内存用完就回收了,堆内存需要调用的变量全部销毁才可以回收。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值