zoukankan      html  css  js  c++  java
  • 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/81078279http://www.cnblogs.com/little-ab/p/6965181.html(推荐)
  • 相关阅读:
    This counter can increment, decrement or skip ahead by an arbitrary amount
    LUT4/MUXF5/MUXF6 logic : Multiplexer 8:1
    synthesisable VHDL for a fixed ratio frequency divider
    Bucket Brigade FIFO SRL16E ( VHDL )
    srl16e fifo verilog
    DualPort Block RAM with Two Write Ports and Bytewide Write Enable in ReadFirst Mode
    Parametrilayze based on SRL16 shift register FIFO
    stm32 spi sdcard fatfs
    SPI bus master for System09 (2)
    SQLSERVER中的自旋锁
  • 原文地址:https://www.cnblogs.com/wfblog/p/8952523.html
Copyright © 2011-2022 走看看