当前位置: 首页 > news >正文

东莞拓步网站建设墙膜 东莞网站建设

东莞拓步网站建设,墙膜 东莞网站建设,广西建设网官方网桂建云,wordpress播放音乐一、JavaScript数据类型原始类型对象类型二、原始类型和对象类型的区别1.原始类型2.引用类型3.复制4.比较5.值传递三、浅拷贝概念实现方法四、深拷贝概念五、浅拷贝、深拷贝和赋值的区别浅拷贝和赋值六、小结想要真正搞明白深浅拷贝#xff0c;你必须要熟练掌握赋值、对象在内…一、JavaScript数据类型原始类型对象类型二、原始类型和对象类型的区别1.原始类型2.引用类型3.复制4.比较5.值传递三、浅拷贝概念实现方法四、深拷贝概念五、浅拷贝、深拷贝和赋值的区别浅拷贝和赋值六、小结想要真正搞明白深浅拷贝你必须要熟练掌握赋值、对象在内存中的存储、数据类型等基础知识。 为了更好地掌握深浅拷贝我们先来看一下数据类型和在内存中的存储形式。 一、JavaScript数据类型 原始类型 Null只包含一个值nullUndefined只包含一个值undefinedBoolean包含两个值true和falseNumber整数或浮点数还有一些特殊值-Infinity、Infinity、NaNString一串表示文本值的字符序列Symbol一种实例是唯一且不可改变的数据类型 对象类型 Object自己分一类丝毫不过分除了常用的ObjectArray、Function等都属于特殊的对象 二、原始类型和对象类型的区别 1.原始类型 在JavaScript中每一个变量都需要一个内存空间来存储。 内存空间被分为两种堆内存和栈内存。 JavaScript中的原始类型的值被直接存储在栈中在变量定义时栈就为其分配好了内存空间。 栈内存特点 存储的值大小固定空间较小可以直接操作其保存的变量运行效率高由系统自动分配存储空间 原始类型的特点就是不可变性即值本身是不可被改变的。 var str JingYu; str.slice(1); str.substr(1); str.trim(1); str.toLowerCase(1); str[0] 1; console.log(str); // JingYu有一个特殊情况 str 6 console.log(str); // JingYu6这个情况是不满足不可变性了吗不是的在上面的代码中我们执行了str ‘6’的操作实际上是在栈中又开辟了一块内存空间用于存储’JingYu6’然后将变量str指向这块空间所以这并不违背不可变性的特点。 2.引用类型 JavaScript中的引用类型(对象类型)的值实际被直接存储在堆内存中在栈内存中只存储了一个固定长度的地址这个地址指向堆内存中的值。 堆内存特点 存储的值大小不定可动态调整空间较大运行效率低无法直接操作其内部存储使用引用地址读取通过代码进行分配空间 引用类型就不具有不可变性的特点了我们可以轻易改变它尤其是数组有很多函数可以改变 pop() 删除数组最后一个元素如果数组为空则不改变数组返回undefined改变原数组返回被删除的元素push()向数组末尾添加一个或多个元素改变原数组返回新数组的长度shift()把数组的第一个元素删除若空数组不进行任何操作返回undefined,改变原数组返回第一个元素的值unshift()向数组的开头添加一个或多个元素改变原数组返回新数组的长度reverse()颠倒数组中元素的顺序改变原数组返回该数组sort()对数组元素进行排序改变原数组返回该数组splice()从数组中添加/删除项目改变原数组返回被删除的元素 3.复制 当我们把一个变量复制到另一个变量的时候原始类型和引用类型的表现也是不同的。 原始类型 var name JingYu; var name2 name; name2 JINGYU; console.log(name); // JingYu;通过输出结果可以看出我们修改name2的结果的时候对name没有任何的影响。那是因为我们将变量name复制给name2的时候是在栈内存空间中创建了一块新的内存空间这块内存空间存储的是变量name2的值值与变量name是相同的但是内存空间地址是完全不同的所以修改name2之后name的值不变。 引用类型 var obj {name:JingYu}; var obj2 obj; obj2.name JINGYU; console.log(obj.name); // JINGYU你会惊奇的发现显示的结果和原始类型是不同的。这又是为什么呢 那是因为当我们复制引用类型的变量时实际上复制的是栈中存储的地址所以复制出来的obj2实际上和obj指向的堆中同一个对象。因此我们改变其中任何一个变量的值另一个变量都会受到影响这就是为什么会有深拷贝和浅拷贝的原因。 4.比较 先看一下代码猜猜运行结果… var name JingYu; var name2 JingYu; console.log(name name2); // true var obj {name:JingYu}; var obj2 {name:JingYu}; console.log(obj obj2); // false对于原始类型比较时会直接比较它们的值如果值相等即返回true。 对于引用类型比较时会比较它们的引用地址虽然两个变量在堆中存储的对象具有的属性值都是相等的但是它们被存储在了不同的存储空间因此比较值为false。 5.值传递 首先给出结论ECMAScript中所有的函数的参数都是按值传递的。 ECMAScript中是没有引用传递的。 let name JingYu; function changeValue(name){name JINGYU; } changeValue(name); console.log(name);很明显上面的执行结果是’JingYu’即函数参数仅仅是被传入变量复制给了的一个局部变量改变这个局部变量不会对外部变量产生影响。 let obj {name:JingYu}; function changeValue(obj){obj.name JINGYU; } changeValue(obj); console.log(obj.name); //JINGYU当函数参数是引用类型时我们同样将参数复制了一个副本到局部变量只不过复制的这个副本是指向堆内存中的地址而已我们在函数内部对对象的属性进行操作实际上和外部变量指向堆内存中的值相同但是这并不代表着引用传递。 let obj {}; function changeValue(obj){obj.name JingYu;obj {name:JINGYU}; } changeValue(obj); console.log(obj.name); // JingYuobj {name:JINGYU};这个只是函数内部的局部对象。 三、浅拷贝 基础知识前面我们已经介绍过了。现在进入我们的正题。 概念 浅拷贝指的是创建新的数据这个数据有着原始数据属性值的一份精确拷贝。 如果属性是基本类型拷贝的就是基本类型的值。如果属性是引用类型拷贝的就是内存地址 即浅拷贝是拷贝一层深层次的引用类型则共享内存地址 实现方法 简单的浅拷贝 function shallowClone(obj) {const newObj {};for(let prop in obj) {if(obj.hasOwnProperty(prop)){newObj[prop] obj[prop];}}return newObj; }在JavaScript中存在浅拷贝现象的还有三种 Object.assign var obj {age: 18,nature: [smart, good],names: {name1: fx,name2: xka},love: function () {console.log(fx is a great girl)} } var newObj Object.assign({}, fxObj);Array.prototype.slice(), Array.prototype.concat() const fxArr [One, Two, Three] const fxArrs fxArr.slice(0) fxArrs[1] love; console.log(fxArr) // [One, Two, Three] console.log(fxArrs) // [One, love, Three]const fxArr [One, Two, Three] const fxArrs fxArr.concat() fxArrs[1] love; console.log(fxArr) // [One, Two, Three] console.log(fxArrs) // [One, love, Three]使用拓展运算符实现的复制 const fxArr [One, Two, Three] const fxArrs [...fxArr] fxArrs[1] love; console.log(fxArr) // [One, Two, Three] console.log(fxArrs) // [One, love, Three]四、深拷贝 概念 深拷贝开辟一个新的栈两个对象属完成相同但是对应两个不同的地址修改一个对象的属性不会改变另一个对象的属性 常见的深拷贝方式 _.cloneDeep() const _ require(lodash); const obj1 {a: 1,b: { f: { g: 1 } },c: [1, 2, 3] }; const obj2 _.cloneDeep(obj1); console.log(obj1.b.f obj2.b.f);// falsejQuery.extend() const $ require(jquery); const obj1 {a: 1,b: { f: { g: 1 } },c: [1, 2, 3] }; const obj2 $.extend(true, {}, obj1); console.log(obj1.b.f obj2.b.f); // falseJSON.stringify() const obj2JSON.parse(JSON.stringify(obj1));但是这种方式存在弊端会忽略undefined、symbol和函数 const obj {name: A,name1: undefined,name3: function() {},name4: Symbol(A) } const obj2 JSON.parse(JSON.stringify(obj)); console.log(obj2); // {name: A}手写循环递归 function deepClone(obj, hash new WeakMap()) {if (obj null) return obj; // 如果是null或者undefined我就不进行拷贝操作if (obj instanceof Date) return new Date(obj);if (obj instanceof RegExp) return new RegExp(obj);// 可能是对象或者普通的值 如果是函数的话是不需要深拷贝if (typeof obj ! object) return obj;// 是对象的话就要进行深拷贝if (hash.get(obj)) return hash.get(obj);let cloneObj new obj.constructor();// 找到的是所属类原型上的constructor,而原型上的 constructor指向的是当前类本身hash.set(obj, cloneObj);for (let key in obj) {if (obj.hasOwnProperty(key)) {// 实现一个递归拷贝cloneObj[key] deepClone(obj[key], hash);}}return cloneObj; }五、浅拷贝、深拷贝和赋值的区别 下面首先借助两张图可以更加清晰看到浅拷贝与深拷贝的区别 从上图发现浅拷贝和深拷贝都创建出一个新的对象但在复制对象属性的时候行为就不一样 浅拷贝只复制属性指向某个对象的指针而不复制对象本身新旧对象还是共享同一块内存修改对象属性会影响原对象 // 浅拷贝 const obj1 {name : init,arr : [1,[2,3],4], }; const obj3shallowClone(obj1) // 一个浅拷贝方法 obj3.name update; obj3.arr[1] [5,6,7] ; // 新旧对象还是共享同一块内存console.log(obj1,obj1) // obj1 { name: init, arr: [ 1, [ 5, 6, 7 ], 4 ] } console.log(obj3,obj3) // obj3 { name: update, arr: [ 1, [ 5, 6, 7 ], 4 ] }但深拷贝会另外创造一个一模一样的对象新对象跟原对象不共享内存修改新对象不会改到原对象 // 深拷贝 const obj1 {name : init,arr : [1,[2,3],4], }; const obj4deepClone(obj1) // 一个深拷贝方法 obj4.name update; obj4.arr[1] [5,6,7] ; // 新对象跟原对象不共享内存console.log(obj1,obj1) // obj1 { name: init, arr: [ 1, [ 2, 3 ], 4 ] } console.log(obj4,obj4) // obj4 { name: update, arr: [ 1, [ 5, 6, 7 ], 4 ] }浅拷贝和赋值 赋值 var obj1{name:张三,age:18,class:[一班]}var obj2obj1//进行了赋值的操作obj2.name李四obj2.class[0]二班console.log(obj1)console.log(obj2)从例子的可以看出赋值后的对象obj2改变原对象obj1的值也改变.这是因为赋值后的对象obj2赋值的是原对象obj1的栈内存地址他们指向的是同一个堆内存数据所以对赋值后的对象obj2对数据进行操作会改变公共的堆内存中的数据所以原对象的值也改变了。 浅拷贝 var obj1{name:张三,age:18,class:[一班]}function qianCopy(obj){var obj2{}for(var attr in obj){//循环对象的所有属性值if(obj.hasOwnProperty(attr)){obj2[attr]obj1[attr]}}return obj2}var obj3qianCopy(obj1)obj3.name李四obj3.age 20obj3.class[0]二·班console.log(obj1)console.log(obj3)从结果可以看出obj3改变了基本类型的值name,并没有使原对象obj1的name改变obj3改变了引用类型的值导致原对象的值也改变了 六、小结 赋值是完全复制将一个对象赋值给另一个对象时只是将一个对象在栈中的内存地址复制给另外一个对象如果改变其中一个对象的属性值时另外一个对象的属性值也会跟着改变 浅拷贝是拷贝一层属性为对象时浅拷贝是复制复制的是对象的内存地址两个对象指向同一个地址 深拷贝是递归拷贝深层次属性为对象时深拷贝是新开栈两个对象指向不同的地址
http://www.dnsts.com.cn/news/5357.html

相关文章:

  • asp网站域名网站站点是什么
  • 网站建设手机字体大小企业网站会涉及到的版权问题
  • 丽水市住房与城乡建设局网站成品网站 高端
  • 自己做网站导航免费咨询会计
  • 做电影网站前途我国档案网站建设研究论文
  • 电脑如何做网站空间化妆品网页设计论文
  • 做网站什么职业百度是网站吗
  • 知名品牌营销策划案例seo推广教学
  • 企业网站建站公司郑州外贸一般上什么网站
  • 做网站选择什么服务器0453牡丹江信息网息网
  • 企业网站分析与优化jira confluence做网站
  • 门网站建设光谷做网站推广怎么样
  • 采集更新wordpressseo推广经验
  • 试卷a《网站建设与管理》设计广告专业制作
  • 营销企业网站制作如何弃掉wordpress版权
  • win8风格网站模板朝阳商城网站建设
  • wordpress能做手机站么本溪网站设计
  • 贝贝网网站开发背景公司网站建设要注意的问题
  • 商洛网站建设求职简历住房和城乡建设岗位证书查询官网
  • 消防网站模板协会门户网站建设
  • 做视频网站 服务器网站制作语言
  • 二手物品交易网站开发环境wordpress自定义提醒用法
  • 哪种语言的网站 做seo更好合肥本地建网站
  • 郑州住房和城乡建设部网站ui设计的细分研究方向包含哪几项
  • 网站流量提升制作网站用什么软件
  • 海口公司网站建设网站建设常用软件jas
  • 如何做网站网页表白网站空间每年继费到哪交
  • 机房网站建设方案北京建设工程招标网
  • 网站备案更改吗顺的网站建设服务
  • 查网站备案名称wordpress友情链接页面插件