JS对象的讲解
1、对象属性的可枚举性和所有权:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Enumerability_and_ownership_of_properties
a、属性的所有权是通过判断该属性是否直接属于某个对象决定的,而不是通过原型链继承的。
b、对象的属性不同于数组,属性是可以从原型上获取到的。所以遍历对象的属性,要分是不是自身的属性,是不是可枚举。
不然很多乱七八糟的属性都出来了,遍历就变得不可控了。(这里不讲人为去设置不可不枚举的功能,我们遍历对象,一般都是遍历自身的属性)
c、自定义的 普通object对象的属性都是可枚举属性。
d、有的操作会忽略enumerable为false的属性。https://www.cnblogs.com/JiAyInNnNn/p/11457323.html
目前,有四个操作会忽略enumerable为false的属性。
for…in循环:只遍历对象自身的和继承的可枚举的属性。
Object.keys():返回对象自身的所有可枚举的属性的键名。
JSON.stringify():只串行化对象自身的可枚举的属性。
Object.assign(): 忽略enumerable为false的属性,只拷贝对象自身的可枚举的属性。
2、对象属性的遍历:https://www.cnblogs.com/chenyablog/p/6477866.html
a、Object.keys():返回一个数组,包括对象 自身的 (不含继承的)所有可枚举属性(不含Symbol属性)。然后使用数组的方法去遍历。【个人喜欢用这种】
b、使用 for..in..遍历:循环遍历对象 自身的 和 继承的 可枚举属性(不含Symbol属性)。
c、使用Object.getOwnPropertyNames(obj)遍历: 返回一个数组,包含对象 自身的所有属性(不含Symbol属性,但是包括不可枚举属性)。
d、使用Reflect.ownKeys(obj)遍历:返回一个数组,包含对象 自身的所有属性,不管属性名是Symbol或字符串,也不管是否可枚举。
总结:普通的object对象属性的遍历,4种方法都可以。因为普通对象的属性都是可枚举的,也不会使用Symbol属性名,且没有继承的属性。如下创建的对象,
var obj = {'0':'a','1':'b','2':'c'};
对象的拷贝
一、场景
除了基本类型跟null,对象之间的赋值,只是将地址指向同一个,而不是真正意义上的拷贝
将一个对象赋值给另外一个对象。
var a = [1,2,3];
var b = a;
b.push(4); // b中添加了一个4
alert(a); // a变成了[1,2,3,4]
自定义对象
var obj = {a:10};
var obj2 = obj;
obj2.a = 20; // obj2.a改变了,
alert(obj.a); // 20,obj的a跟着改变
这就是由于对象类型直接赋值,只是将引用指向同一个地址,导致修改了obj会导致obj2也被修改
二、浅拷贝
所以,我们需要封装一个函数,来对对象进行拷贝,通过for in 循环获取基本类型,赋值每一个基本类型,才能真正意义上的复制一个对象
var obj = {a:10};
function copy(obj){
var newobj = {};
for ( var attr in obj) {
newobj[attr] = obj[attr];
}
return newobj;
}
var obj2 = copy(obj);
obj2.a = 20;
alert(obj.a); //10
这样就解决了对象赋值的问题。
三、深拷贝
但是这里存在隐患,如果obj中,a的值不是10,而是一个对象,这样就会导致在for in中,将a这个对象的引用赋值为新对象,导致存在对象引用的问题。
var obj = {a:{b:10}};
function copy(obj){
var newobj = {};
for ( var attr in obj) {
newobj[attr] = obj[attr];
}
return newobj;
}
var obj2 = copy(obj);
obj2.a.b = 20;
alert(obj.a.b); //20
因此,由于这个copy对象只是对第一层进行拷贝,无法拷贝深层的对象,这个copy为浅拷贝,我们需要通过递归,来拷贝深层的对象。将copy改造成递归即可
var obj = {a:{b:10}};
function deepCopy(obj){
if(typeof obj != 'object'){
return obj;
}
var newobj = {};
for ( var attr in obj) {
newobj[attr] = deepCopy(obj[attr]);
}
return newobj;
}
var obj2 = deepCopy(obj);
obj2.a.b = 20;
alert(obj.a.b); //10
注:支持es6的浏览器,有更简单的方法 https://blog.csdn.net/u012814856/article/details/81078279 或 http://www.cnblogs.com/little-ab/p/6965181.html(推荐)
JS对象的讲解的更多相关文章
- js对象详解
js自定义对象 一,概述 在Java语言中,我们可以定义自己的类,并根据这些类创建对象来使用,在Javascript中,我们也可以定义自己的类,例如定义User类.Hashtable类等等. 目前在J ...
- js对象的定义及处理
一,概述 在Java语言中,我们可以定义自己的类,并根据这些类创建对象来使用,在Javascript中,我们也可以定义自己的类,例如定义User类.Hashtable类等等. 目前在Javascrip ...
- js对象属性方法大总结(收集)
数组(Array):系列元素的有序集合: 详细演示请看:[js入门系列演示·数组 ] http://www.cnblogs.com/thcjp/archive/2006/08/04/467761.ht ...
- js对象属性方法大总结
数组(Array):系列元素的有序集合: 详细演示请看:[js入门系列演示·数组 ] http://www.cnblogs.com/thcjp/archive/2006/08/04/467761.ht ...
- js 深入原理讲解系列-Promise
js 深入原理讲解系列-Promise 能看懂这一题你就掌握了 js Promise 的核心原理 不要专业的术语,说人话,讲明白! Q: 输出下面 console.log 的正确的顺序? const ...
- JS对象继承篇
JS对象继承篇 ECMAScript只支持实现继承,而且其实现继承主要是依靠原型链来实现的 原型链 其基本思路是利用原型让一个引用类型继承另一个引用类型的属性和方法 function Person() ...
- JS 对象封装的常用方式
JS是一门面向对象语言,其对象是用prototype属性来模拟的,下面,来看看如何封装JS对象. 常规封装 function Person (name,age,sex){ this.name = na ...
- JSON字符串和JS对象之间的转换
JSON字符串和JS对象之间的转换 1 json字符串转换为js对象 1.1 标准json格式字符串转换为Js对象 JSON字符串 str JSON.parse(str) eval(str) eva ...
- js 对象的_proto_
js 对象呢,有个属性叫_proto_,以前没听说过,也没关注,最近看这个原型,就被迫知道了这个东西,js 这里面的东西,真是规定的很奇怪,具体为啥也不知道,就测试发现的,对象的_proto_属性,和 ...
随机推荐
- MPU6050寄存器记录
参考资料:http://blog.sina.com.cn/s/blog_8240cbef01018i10.html 不过有一些寄存器没有写到,所以我自己加一点: 1)Register 25 - IN ...
- paper 133:结构张量Structure Tensor(一)
1.结构张量的作用: 能够区分图像中的平坦区域,边缘,角点: 2.图像中的结构张量的定义 1)是一个矩阵: 2)与图像的水平,垂直梯度有关,定义如下: 在MATLAB中,可以用 ...
- 探索Redis设计与实现11:使用快照和AOF将Redis数据持久化到硬盘中
本文转自互联网 本系列文章将整理到我在GitHub上的<Java面试指南>仓库,更多精彩内容请到我的仓库里查看 https://github.com/h2pl/Java-Tutorial ...
- 【运维】使用Serv-U搭建FTP服务器
1.先安装好Serv-U,并作为系统服务安装 2.打开Serv-U,新建一个域 3.添加用户 4.解决阿里云专有网络的一个问题 遇到一个情景:需要使用Serv-U进行FTP更新软件,其中使用PASV的 ...
- VMware 虚拟机NAT模式如何设置网络连接,从头到尾全过程~!!
一.首先查看自己的虚拟机服务有没有开启,选择电脑里面的服务查看: 1.计算机点击右键选择管理 2.进入管理选择VM开头的服务如果没有开启的话就右键开启 二.虚拟机服务开启后就查看本地网络虚拟机的网 ...
- FATFS模块应用笔记
FATFS模块应用笔记 如何港 范围 内存使用 模块尺寸缩小 长文件名 统一的API 重入 复制文件访问 性能有效文件访问 对闪存介质考虑 关键的第 延长使用FATFS API 关于FATFS许可证 ...
- git for windows 2.1版本git bash下git log乱码修复
git bash,输入以下命令git config --global i18n.logoutputencoding utf-8git config quotepath false关闭git bash, ...
- Neo4j parameter
Neo4j browser: $ :help param Set a parameter Set a parameter to be sent with queries. The :param nam ...
- pytest_参数化3
import pytesttest_user_data=[ {'user':'linda','password':'8888'}, {'user':'servenruby','password':'1 ...
- OI中的快速傅里叶变换(FFT)
快速傅里叶变换(FFT) ---- LLpp ...