对象详解

Object.prototype.hasOwnProperty() 返回布尔

(原型对象的方法)
表示是否是对象自身的属性。所有实例对象都可以访问
这个方法会查找一个对象是否有某个属性,但是不会去查找它的原型链
沿原型链上查找的方法不是它自身的

Object.defineProperty() 类方法

  • 作用:
    1. 给对象动态添加属性
    2. 将对象属性绑定到另一个对象上(见下)
    3. 数据劫持-监听对象数据变化, 实现数据变化自动更新界面 (vue2.x实现原理应用)(见下)

  • 语法
    Object.defineProperty(obj, prop, descriptor)

  • 参数

obj : 要定义属性的对象。
prop:要定义或修改的属性的名称或 Symbol 。
descriptor:要定义或修改的属性描述符对象。

  • 数据属性:

1.configurable:表示能否通过delete删除属性从而重新定义属性,
能否修改属性的特性,或者能否把属性修改为访问器属性,默认值为false。
2.enumerable:表示能否通过for in循环访问属性,默认值为false
3.writable:表示能否修改属性的值。默认值为false。
4.value:包含这个属性的数据值。默认值为undefined。

  • 访问器属性:

1.get:在读取 / 访问属性时自动调用的函数,默认值是undefined
2.set:在 写入 / 赋值 属性的时自动调用的函数,默认值是undefined

function test1() {let obj = {}Object.defineProperty(obj, 'name', {value: 'jack',configurable: true, // 允许删除属性writable: true, //允许修改属性值enumerable: true, // 遍历对象for-in})// obj = {name:'jack'}console.log(obj.name)// delete obj.name  // 删除对象属性// obj.name = 'rose' // 修改对象属性值console.log(obj.name)for (const key in obj) {console.log(key, obj[key])}}let obj = {}Object.defineProperty(obj,'age',{// 访问对象age属性时自动调用  obj.ageget:function(){console.log('get >>>> ')return 20},// 赋值给对象属性age时自动调用并赋值set(newValue){// this.age = newValueconsole.log('set >>>> ')}})console.log('111',obj.age)obj.age = 18console.log('222',obj.age)
  • 返回值

    被传递给函数的对象。

作用

1、 将对象属性绑定到另一个对象上

<!-- Object.defineProperty作用1. 将对象属性绑定到另一个对象上--></head><body><script>let obj = {name: 'jack',age: 18,}let vm = {}// 将obj对象的所有属性动态添加到vm对象上//1. 遍历obj对象for (const key in obj) {// 2. 动态给vm添加属性Object.defineProperty(vm, key, {// vm.nameget() {return obj[key]},// vm.name = 'rose'set(newValue) {// 原值与新值相同直接返回if (obj[key] == newValue) {return}obj[key] = newValue // 设置属性新值},})}</script></body>

2、 数据劫持—利用set,在 赋值 属性的时自动调用的函数,实现自动刷新

<!-- 数据劫持将obj对象的属性能过Object.defineProperty方法绑定到vm对象上,转变成getter和setter方法.vm对象数据变化,自动更新界面vm.message = 'helloworld'-->
</head>
<body><div>内容</div><script>let obj = {message:''}let vm = {}for(const key in obj){Object.defineProperty(vm, key, {get(){return obj[key]},set(value){obj[key] = value// 更新div内容document.querySelector('div').innerHTML = value}})}</script>
</body>

代理Proxy

理解:简单理解就是我们不直接对对象、函数或者数组进行操作,而是把它挂载到Proxy(代理)上,直接对代理的做一系列操作。我们去买房,房产中介就相当于我们的代理,我们不需要直接向卖家沟通。

捕获器(trap)

使用代理的主要目的是可以定义捕获器(trap)。捕获器就是在处理程序对象中定义的“基本操作的“拦截器”。
每个处理程序对象可以包含零个或多个捕获器,每个捕获器都对应一种基本操作,可以直接 或间接在代理对象上调用。每次在代理对象上调用这些基本操作时,代理可以在这些操作传播到目标对 象之前先调用捕获器函数,从而拦截并修改相应的行为。
捕获器一共13种
apply 、construct、defineProperty、deleteProperty、
get、getOwnPropertyDescriptor、getPrototypeOf、has、isExtensible
ownKeys、preventExtensions、set、setPrototypeOf

get()


get 的参数: target 目标对象 property 属性 receiver 处理程序

set()—设置新值触发



示例: 不改变原对象,检查年龄数据类型number, 给年龄后添加岁字

代理的应用—实现页面更新

<body><div></div><script>let obj = {message:''}let proxyObj = new Proxy(obj,{get(target,propery){return target[propery]},set(target,propery,value){target[propery] = value // 通过代理对象改变目标对象属性值// 更新界面操作-更改div内容document.querySelector('div').innerHTML = value}})proxyObj.message = 'hello'</script>
</body>

代理Proxy与Object.definePropery区别

       Object.definePropery 处理数组要特殊处理   都需要用一个循环代理Proxy 直接处理

TodoList 案例改进

<body><div class="container"><input type="text" placeholder="请输入内容" /><button>确定</button><ul></ul></div><script>// 目标对象var arr = ['html', 'css'] // 数据// 代理对象let proxyArr = new Proxy(arr,{get(target,propery){return target[propery]},set(target,propery,value){target[propery] = value// 代理对象数组数据变化,自动刷新界面showList()return true //???}})/*数据操作-实现显示列表遍历数组,拼接字符串,将字符串作用内容设置给显示元素点击确定按钮,获取输入框内容,添加数组*/function showList() {var liArr = proxyArr.map(function (item, index) {return `<li data-index="${index}">${item}</li>`})var liStr = liArr.join('')var ulEle = document.querySelector('ul')ulEle.innerHTML = liStr}// 删除元素function onDelete() {//  删除事件操作委托给ul上级元素处理var ulEle = document.querySelector('ul')ulEle.addEventListener('click', function (e) {e = e || window.eventvar target = e.target || e.srcElement // 事件目标对象var index = target.dataset.indexproxyArr.splice(index, 1)})}//添加元素function bindAdd() {var btn = document.querySelector('button')btn.onclick = function () {var inputEle = document.querySelector('input')var inputValue = inputEle.valueproxyArr.push(inputValue)inputEle.value = '' // 清空输入框}}showList() // 初始化执行onDelete() // 初始化执行bindAdd() // 初始化绑定添加事件</script></body>

浅拷贝 深拷贝

一、先了解内存

  1. 内存简单划分为堆区域和栈区域
  2. 复杂数据类型数据存储在堆区域,基本数据类型变量和引用变量存储在栈区域
    二、拷贝- 复制obj对象得到一个全新的对象
    1、浅拷贝 – 复制的obj对象只复制一层,如果对象属性值中有对象,则对象不能复制(如fun:{})只能赋值对象的地址
    2、深拷贝 – 完全复制的obj对象,如果对象属性值是对象一起复制得到全新对象


浅拷贝:

深拷贝:

Object.assign(obj)或展开运算符{…obj}
缺点:只能拷贝一层,如果属性值是对象,无法拷贝
let newObj = obj //不是拷贝,只是将地址给了newObj,还是同一个对象
展开运算符实现的是浅拷贝;只能拷贝一层,如果属性值是对象,无法拷贝

深拷贝

JSON对象

  • JSON.stringify(obj)

              obj -> 字符串  对象转字符串注: 只能是Object形式对象,不能是Math,Date...'{name:"jack",age:18,fun:{swiming:"游泳"}}'  <- JSON字符串
    


  • JSON.parse(str)

              字符串 -> obj  对象注: 字符串必须 是 json格式
    


利用JSON实现深拷贝

  1. JSON.parse(JSON.stringify(obj))
    缺点: 数据类型是Function或数据值为undefined无法拷贝
  // 利用JSON实现深拷贝let obj = {name: 'jack',age: 18,fun: {swiming: '游泳',},say:function(){console.log('说话');},score:undefined}// let str = JSON.stringify(obj)  //obj->str// let newObj = JSON.parse(str)  // str->objlet newObj = JSON.parse(JSON.stringify(obj))newObj.name = 'rose'newObj.age = 20newObj.fun.swiming = '玩游戏'console.dir(newObj)console.dir(obj)

3. 递归 cloneDeep()—完美的拷贝,完全拷贝

<body><script>function cloneObj(obj){let newObj = Array.isArray(obj)? []:{} // 存储拷贝的原对象属性方法for(const key in obj){if(obj[key] && typeof obj[key] === 'object'){newObj[key] = cloneObj(obj[key])}else{newObj[key] = obj[key]}}return newObj}let obj = {name: 'jack',age: 18,fun: {swiming: '游泳',},say: function () {console.log('说话')},score: undefined,}let newObj = cloneObj(obj)newObj.name = 'rose'newObj.age = 20newObj.score = 98newObj.fun.swiming = '玩游戏'console.dir(newObj)console.dir(obj)</script></body>

JavaScript高级编程--对象详解相关推荐

  1. javascript之window对象详解

    window对象有以下方法: open  close  alert   confirm   prompt   setTimeout  clearTimeout   setInterval   clea ...

  2. JavaScript中 FormData 对象详解

    简介: FormData 对象用以将数据编译成键值对,以便用 XMLHttpRequest 来发送数据. 主要用于:发送表单数据,也可用于发送带键数据(keyed data),而独立于表单使用. 如果 ...

  3. [Javascript]:BOM对象详解和BOM与DOM的层次关系

    BOM与DOM的结构层次图 BOM对象是什么 BOM:浏览器对象模型(Brower Object Model),是用于操作浏览器而出现的API,BOM对象则是Javascript对BOM接口的实现. ...

  4. Unix环境高级编程-文件系统详解

    文件系统: 知识性的内容 一.目录和文件 1.获取文件属性 stat,fstat,lstat stat:通过文件路径,获取属性,面对符号链接文件时,获得的是所指向的文件的属性 fstat:通过文件描述 ...

  5. 【JavaScript 教程】ES6 中的 Promise对象 详解

    [JavaScript 教程]ES6 中的 Promise对象 详解 1.Promise对象含义 promise是异步编程的一种解决方法. 所谓promise,简单说是一个容器,里面保存着某个未来才会 ...

  6. javascript BOM对象详解

    javascript BOM对象详解 目标:本章节将分为9点详细介绍有关BOM对象的知识点 1.什么是BOM 2.BOM的构成 3.顶级对象window 4.window对象常见事件(页面加载事件和体 ...

  7. Javascript中的Document对象详解

    Document对象详解 document 文挡对象 - JavaScript脚本语言描述           -------------------------------------------- ...

  8. html内置时间对象,JavaScript中的常用事件,以及内置对象详解

    原标题:JavaScript中的常用事件,以及内置对象详解 今天是刘小爱自学Java的第81天. 感谢你的观看,谢谢你. 话不多说,开始今天的学习: 学前端有一个非常权威的组织,也就是w3c,其有个专 ...

  9. JavaScript Date对象详解 以及 时间戳和时间的相互转换

    目录 一.Date对象详解 1.Date对象 2.创建Date对象 3.Date对象属性 4.Date对象方法 5.Date对象的应用(节流函数时间戳写法) 二.时间戳和时间的相互转换 1.时间转换为 ...

最新文章

  1. day04-html
  2. 每个程序员都应该挑战的6个项目
  3. 音视频技术开发周刊 | 174
  4. 2018暑假集训---递推递归----一只小蜜蜂hdu2044
  5. Python这个超炫的黑科技,可全网爬取各种资源,建议收藏!!
  6. 电商C4D素材,玩转立体作品不是问题
  7. 前端从入门到精通(记录自己的前端学习之路)都是一些自己做的笔记
  8. 《众妙之门——用户体验设计的秘密》一1.4 良性的问题解决案例
  9. 变频器基础:变频器工作原理与常用功能
  10. oracle 12c PDB 数据库 和mybatis 数据库连接池 的连接问题
  11. Frame-Relay基础及配置学习笔记
  12. 计算机登录域时很慢,新装WIN7电脑加入域后,变的很慢
  13. AutoCAD2007 打开缓慢解决方案
  14. 二进制图片转换成BMP位图(C++)
  15. 橙仕汽车——双排mini卡
  16. 一维离散动力学系统的混沌研究【基于matlab的动力学模型学习笔记_8】
  17. 调查计算机对运算能力的影响,计算器对运算能力的影响
  18. 使用码云同步谷歌 Chrome 浏览器书签
  19. 闭关28天,奉上[Java一线大厂高岗面试题解析合集],备战金九银十
  20. 西班牙语基础必备词汇(动物和食物)

热门文章

  1. 【转载】站在牛顿墓前 文/张琦(北京大学)
  2. 用c语言实现扫雷小游戏。
  3. 【Python】max()中key的使用
  4. 如何找win10 软件商店里下载的python路径并删除
  5. Delphi使用ADOconnection连接mysql数据库时的Connectionstring问题
  6. Linux-smb服务器搭建
  7. 如何一键去除Word文件中的水印
  8. vue实现Dropdown下拉菜单
  9. 文章阅读总结:GPT
  10. 一款全面高效的日志分析工具,操作更简单