首页 > 其他分享 >Object的相关内容及深拷贝和浅拷贝

Object的相关内容及深拷贝和浅拷贝

时间:2022-08-27 11:16:34浏览次数:58  
标签:obj log 对象 Object 内容 console 拷贝 属性

概述:

Object是顶层的构造,万物皆对象,所有的对象都是Object的子类。Object的方法所有的对象都能共享。

 

Object实例方法(原型方法)

使用实例对象调用的方法称为实例方法。所有实例都是Object的子类,所以所有的实例都能调用Object的实例方法。

已经废弃的方法

defineGetter 定义get
defineSetter 定义set
lookupSetter 导出对应的set方法
lookupGetter 导出对应get方法

class Person{
   constructor(){
       this.age = 18
  }
}
//调用对应的__defineGetter
let person = new Person()
//定义get 访问对应的属性的时候调用的方法 属性名   handler
person.__defineGetter__('age',function(){
   console.log('getter调用了');
   return '18'
})
console.log(person.age);
//定义对应的set 用于设置的时候
person.__defineSetter__('username',function(value){
   console.log('setter调用了 传入的值'+value);
   // this.username = value 循环调用问题 递归死循环
})
person.username = 'jack'
console.log(person);
//获取对应的get方法 指定的属性
let get = person.__lookupGetter__('age')
let set = person.__lookupSetter__('username')
console.log(get);
console.log(set);

hasOwnProperty 判断对象上是否具备属性(不会原型中获取)*


class Person{
   constructor(){
       this.age = 18
  }
}
Person.prototype.username = 'jack'
let person = new Person()
person.sex = '女'
//判断对象上是否具备属性 返回布尔类型
console.log(person.hasOwnProperty('age')); //true
console.log(person.hasOwnProperty('sex')); //true
console.log(person.hasOwnProperty('username')); //false

isPrototypeOf 判断当前对象(构造函数的原型对象)是否处在对应参数对象的原型链上 返回布尔类型 *


class Son extends Person{
   constructor(){
       super()
  }
}
//判断当前对象(构造函数)是否处在对应参数对象的原型链上 返回布尔类型
console.log(Object.prototype.isPrototypeOf(person)); //true
let son = new Son()
console.log(Person.prototype.isPrototypeOf(son)); //true

propertyIsEnumerable 指定属性是否可以枚举(如果对象没有指定的属性,则此方法返回 false


// 返回boolean类型 属性是否是可以枚举(可以遍历 for-in遍历)
let obj = {
   arr:[1,2,3],
   o:{key:1},
   v:123,
   f:()=>{},
   b:false
}
//判断当前属性是否可以枚举 可以遍历
console.log(obj.propertyIsEnumerable('v')); //true
console.log(obj.propertyIsEnumerable('arr')); //true
console.log(obj.propertyIsEnumerable('o')); //true
console.log(obj.propertyIsEnumerable('f')); //true
console.log(obj.propertyIsEnumerable('b')); //true

所有的内置属性都是false(symbol做为对象的key被设置在底层) 所有的自定义属性返回的都是true

valueOf 提取对应的值 toString 转为string字符串 toLocaleString 转为本地的字符串


// valueOf提取对应的值
console.log(new Object().valueOf());
// toString 转为字符串类型 引用类型出现的结果[object Object]
console.log(new Object().toString());
//toLocalString 转为本地格式的字符串 千位分隔
console.log(Number(123456789).toLocaleString());

Object的实例属性

__proto__ 隐式原型

let obj = new Object()
console.log(obj.__proto__)
constructor 构造器

let obj = new Object()
console.log(obj.constructor) //指向对应的构造函数

Object的静态方法

通过类名通过,只能被Object类名调用。

assign 将后面的对象拷贝到第一个对象里面 返回的是一个新的对象 这个对象和原本第一个对象的地址一致(实现浅拷贝)(*)

// 将后面的对象给到前面的对象 assign 返回一个新的对象 新的对象会和第一个对象的地址一样
let target = {}
let obj =  Object.assign(target,{name:'jack'},{age:18})
console.log(obj);
console.log(target);
create 根据对应传入的对象创建同类型的对象 创建的新对象的原型里面包含了对应传入对象 (*)

//create 创建一个对象
let obj1 = {name:"张三"}
let obj2 = Object.create(obj1)
console.log(obj2); //将对应obj1加到对应的obj2的原型上
console.log(obj2 == obj1);
class Person{
   constructor(){
       this.name = 'tom'
  }
}
let person = Object.create(Person) //根据传入的对象的类型来创建对应的对象
console.log(person); //函数 Class本质就是构造函数
keys values entries 获取对应对象的所有的key 和 value 以及相关键值对 (*)

//keys values entries 返回的都是一个迭代器
let obj = {
   name:'jack',
   age:18,
   sex:'男'
}
//获取所有的key
let objKeys = Object.keys(obj) //返回所有key组成的伪数组
//获取所有的value
let objValues = Object.values(obj) //返回所有key组成的伪数组
//获取所有的键值对
let objEntries = Object.entries(obj) //返回所有key组成的伪数组
console.log(objKeys);
console.log(objValues);
console.log(objEntries);
//这三个获取到的数组都可以进行遍历
objEntries.forEach(arr=>{
   console.log(`key:${arr[0]} value : ${arr[1]}`);
})
is 判断俩个对象是否是一个 (*)

//is
console.log(Object.is(NaN,NaN)); //true
//assign 实现浅拷贝
let obj1 = Object.assign(obj)
console.log(Object.is(obj1,obj)); //true
console.log(Object.is({},{})); //false
console.log(Object.is(null,null)); //true
console.log(Object.is(null,undefined)); //false
冻结(只读) freeze 是否冻结 isFrozen (*)

//使对象冻结 不能进行修改 (只读 包含不可扩展 以及密封)
Object.freeze(obj)
obj.age = 20 //不能进行修改
console.log(obj);
delete obj.name  //无用操作
//打印当前对象是否冻结
console.log(Object.isFrozen(obj)); //true
密封 (不能添加和删除属性) seal 是否密封 isSealed (*)

//使对象密封 不能进行delete操作 以及不能添加新的属性
Object.seal(obj)
delete obj.name //无用操作
console.log(obj);
//打印当前对象是否密封
console.log(Object.isSealed(obj)); //true
不可扩展 (不能添加)preventExtensions 是否可扩展 isExtensible (*)

//使对象不能扩展 不能添加新的属性
Object.preventExtensions(obj)
obj.username = '张三' //无用操作
console.log(obj);
//打印当前对象是否可扩展
console.log(Object.isExtensible(obj)); //false
getPrototypeOf 获取指向的原型对象 setPrototypeOf 设置新的原型对象(*)

// getPrototypeOf 原型获取
// setPrototypeOf 原型设置 将对应的第二个参数赋值给对应的第一个参数的原型
//在原型上进行设置 目标对象 key:value 传入对应的key和value
//第一个为目标对象 第二个为原型对象
let obj = {}
Object.setPrototypeOf(obj,{
   username:'jack',
   age:18
})
console.log(obj.username);//obj的这个原型上进行设置
console.log(obj.age);//obj的这个原型上进行设置
let obj1 = new Object()
console.log(obj1.username); //undefined
//getPrototypeOf 获取指向的原型对象
let pro = Object.getPrototypeOf(obj)
let obj1Pro = Object.getPrototypeOf(obj1)
console.log(pro); //{username:'jack',age:18}
console.log(pro == Object.prototype);//false
console.log(obj1Pro == Object.prototype);//Object.prototype true
getOwnPropertyDescriptor 获取属性详情对象 getOwnPropertyDescriptors 获取所有的属性详情对象 (*)

let obj = {
   name:'jack'
}
//getOwnPropertyDescriptorc 获取属性的详情信息 返回一个属性对象(es的内置对象)
let property =  Object.getOwnPropertyDescriptor(obj,'name')
console.log(property);

 


//获取所有的属性详情信息 返回也是一个对象 这个对象里面包含对应的key 值为对应的属性对象
let objs =  Object.getOwnPropertyDescriptors(obj)
console.log(objs);

 

getOwnPropertyNames 获取所有属性名组成的数组(不包含symbol值属性名) getOwnProperSymbols 获取属性名为symbol值的属性组成的数组

//获取所有的属性名 组成一个数组或者是伪数组
console.log(Object.getOwnPropertyNames(obj));
let sy = Symbol()
obj[sy] = 'hello'//属性名为symbol的属性
//获取所有属性名为symbol值的属性
console.log(Object.getOwnPropertySymbols(obj));
defineProperty 定义一个属性 ( vue2的底层实现 ***)

let obj = {}
//给对象添加属性
// defineProperty 定义一个属性 参数是对象 属性名 属性对象
// (属性对象 value 对应的值 writeable 是否可以修改 enumerable 是否可以遍历 configurable 删除可以删除)
Object.defineProperty(obj,'name',{
   value:'jack',
   writable:true, //可以修改
   enumerable:true, //可以遍历 for in
   configurable:true //可以删除
})
console.log(obj); //多一个name属性
obj.name = 'hello' //跟writable属性相关为false就不能修改
delete obj.name //跟configurable相关 为false 不能删除
console.log(obj);
for(let key in obj){
   console.log(key); //enumerable为false 就不能进行遍历
}
属性对象的基础属性

value 值

writeable 是否可以设置

enumerable 是否可以遍历

configurable 是否可以删除

属性对象的访问器属性 (已经存在的情况才可以调用)

get 表示获取(函数)

set 表示设置 (函数)

enumerable 是否可以遍历

configurable 是否可以删除


//以访问器属性来写(后面的俩个内容可以不写默认为false)
Object.defineProperty(obj,'age',{
   set(value){ //设置值的时候调用 value等于后面传递的值
       console.log('set执行了');
       mockObj.age = value
  },
   get(){ //获取值的时候
       console.log('get执行了');
       return mockObj.age
  },
   // enumerable:true, //可以遍历 for in
   // configurable:true //可以删除
})
console.log(obj.age); //调用了get的返回值
obj.age = 20 //调用了set方法
console.log(obj.age); //调用了get的返回值
delete obj.age
console.log(obj.age);
console.log(obj);

vue2是由对应的Object.defineProperty和观察者模式实现

defineProperties 定义多个属性

// defineProperties 定义多个属性 对象 属性对象
let object = {

}
Object.defineProperties(object,{
   name:{
       writable:true,
       value:"张三",
       enumerable:true,
       configurable:true
  },
   sex:{
       // writable:true,
       // value:"男",
       enumerable:true,
       configurable:true,
       get(){
           return '男'
      },
       set(value){
           console.log('设置方法调用了')
      }
  }
})
console.log(object);

vue2双向数据绑定实现

v-model来实现双向数据绑定

<!DOCTYPE html>
<html lang="en">

<head>
 <meta charset="UTF-8">
 <meta name="viewport" content="width=device-width, initial-scale=1.0">
 <meta http-equiv="X-UA-Compatible" content="ie=edge">
 <title>Document</title>
</head>

<body>
 <div id="app">
       <input type="text" v-model="message">
      {{message}}
 </div>
 <script src="./lib/vue.js"></script>
 <script>
   new Vue({
     el: "#app",
     data: {
       message:"你好啊"
    }
  })
 </script>
</body>

</html>
底层实现(模拟实现)

<!DOCTYPE html>
<html lang="en">

<head>
   <meta charset="UTF-8">
   <meta http-equiv="X-UA-Compatible" content="IE=edge">
   <meta name="viewport" content="width=device-width, initial-scale=1.0">
   <title>Document</title>
</head>

<body>
   <div id="app">
       <input type="text" v-model="message">
      {{message}}
       <input type="text" v-model="title">
      {{title}}
   </div>
</body>
<script>
   class Vue {
       constructor(option) {
           this.option = option
           //通过对应的el属性传入的选择器选择对应的元素
           this.el = document.querySelector(option['el'])
           //提取data
           this.data = option['data']
           //虚拟对象
           this.mockData = {}
           //获取初始的模板
           this.template = this.el.innerHTML
           this.rander() //初次渲染
           this.wacth() //调用监听
      }
       rander() {
           let that = this
           //读取{{}}包起来的内容 替换
           //{{}}
           this.el.innerHTML = this.template.replace(/\{\{[\w.]+\}\}/g, function (v) { //表示匹配的内容
               // v {{message}} ==> 你好啊
               let key = v.substr(2, v.length - 4)
               return that.data[key] //调用get
          })
           //读取对应的input的v-model属性
           //找所有的input框 在input在所有有对应的v-model属性 将他里面的value值变了
           Array.from(this.el.querySelectorAll('input'))
               //得到所有代理v-model属性的input框
              .filter((input) => input.attributes['v-model'])
               //接着遍历
              .forEach(vmInput => {
                   //给对应的value进行赋值
                   vmInput.value = that.data[vmInput.getAttribute('v-model')] //调用get
                   //给对应的input框添加事件 oninput事件
                   vmInput.oninput = function () {//观察者
                       that.data[vmInput.getAttribute('v-model')] = this.value //调set
                       vmInput.focus() //获取焦点
                  }
              })
      }
       //监听
       wacth() {
           let _this = this
           Object.keys(this.data).forEach(key => {
               _this.mockData[key] = _this.data[key] //初始赋值操作
               Object.defineProperty(_this.data, key, {
                   get() {
                       return _this.mockData[key]
                  },
                   set(value) {
                       _this.mockData[key] = value
                       _this.rander()
                  }
              })
          })
      }

  }
   new Vue({
       el: "#app",
       data: {
           message: "你好啊",
           title:'你好'
      }
  })
</script>

</html>

 

标签:obj,log,对象,Object,内容,console,拷贝,属性
From: https://www.cnblogs.com/bigBossKiss/p/16629976.html

相关文章

  • 浅拷贝和深拷贝的概念及方法
    浅拷贝只拷贝第一层的值,其他后面拷贝的是地址。示例使用u盘在一台电脑上拷贝文件,使用浅拷贝拷贝的相当于快捷方式。第一层两个内容不一样,其他每层都是指向同一个文件......
  • MBR病毒IDA逆向分析与重写内容解读
    1运行病毒拍摄快照运行病毒,直接关机重启后出现下面的页面输入任意字符,回车后会清空可以知道,该病毒破坏了windows的启动过程,要进入系统必须输入正确的口令,该病毒......
  • JS中实现浅拷贝与深拷贝的几种方式
    浅拷贝只拷贝第一层的值,其他后面拷贝的是地址,拷贝后的对象与原对象不是同一个地址,拷贝时会开一个内存给拷贝的对象第一层进行值拷贝,第二层及之后进行地址拷贝示例:快捷......
  • Object的相关内容
    概述:      Object是顶层的构造,万物皆对象,所有的对象都是Object的子类。Object的方法所有的对象都能共享。        Object实例方法(原型方......
  • python基础-set集合,深浅拷贝
    python基础-set集合,深浅拷贝  一.基础数据类型补充补充给一个字符串基本操作 列表:循环删除列表中的每一个元素 分析原因:for的运行过程.会有一个......
  • Objective-c
    标注10天的课程,打算2天看完,改成3天看完,最后4天看完了,Objective-c基于c,加了面向对象的思想和自己的一些奇怪的语法,万变不离其宗。感觉最大的收获是学了很多内存管理的知识。......
  • C语言重定向输入:txt文件内容是中文,重定向输入显示乱码的原因
    一.txt文件中的内容是中文,重定向输入显示乱码原因:是因为文本文件的编码和和编译器的不一致导致的.我文本文件用的编码是UTF-8,而编译器是ANSI,不匹配,所以输出乱码.文本......
  • 理解深浅拷贝
     拷贝不能脱离数据类型来谈数据类型除ES6引入的Symbol和BigInt数据类型,JS数据可大致分为:基本数据类型(String、Number、Boolean、Null、Undefined)和......
  • Unable to create an object of type 'DbContext'问题解决,网上搜来的没一个对的。
    用了很久的EFCore了,第一次遇到这个问题,觉得很奇怪,baidu了一下,都是要提供设计时工厂的答案。很明显这个做法是有问题的,都是DI的年代了,你的DbContext又不是动态生产了一堆......
  • excel如何将多个单元格内容合并到一个单元格中
    excel应用过程中经常会有需要将多个单元格的内容合并在一起输入到单元格当中,这里给大家分享一下方法工具/原料excel2016方法/步骤 将单元格A2,B2,C2中的......