zoukankan      html  css  js  c++  java
  • js你不知的那些基础问题-对象

    1 属性的删除:delete 命令

    delete命令用于删除对象的属性,删除成功后返回true

    var obj = { p: 1 };
    Object.keys(obj) // ["p"]
    
    delete obj.p // true
    obj.p // undefined
    Object.keys(obj) // []
    

      上面代码中,delete命令删除对象objp属性。删除后,再读取p属性就会返回undefined

      而且Object.keys方法的返回值也不再包括该属性。

      注意,删除一个不存在的属性,delete不报错,而且返回true

    var obj = {};
    delete obj.p // true
    

      上面代码中,对象obj并没有p属性,但是delete命令照样返回true

      因此,不能根据delete命令的结果,认定某个属性是存在的。

      只有一种情况,delete命令会返回false,那就是该属性存在,且不得删除

    var obj = Object.defineProperty({}, 'p', {
      value: 123,
      configurable: false
    });
    
    obj.p // 123
    delete obj.p // false
    

      上面代码之中,对象objp属性是不能删除的,所以delete命令返回false

      (关于Object.defineProperty方法的介绍,请看《标准库》的 Object 对象一章)。

      另外,需要注意的是,delete命令只能删除对象本身的属性,

      无法删除继承的属性(关于继承参见《面向对象编程》章节)。

    var obj = {};
    delete obj.toString // true
    obj.toString // function toString() { [native code] }
    

      上面代码中,toString是对象obj继承的属性,虽然delete命令返回true

      但该属性并没有被删除,依然存在。这个例子还说明,即使delete返回true,该属性依然可能读取到值。

    1.1 属性是否存在:in 运算符

      in运算符用于检查对象是否包含某个属性(注意,检查的是键名,不是键值),

      如果包含就返回true,否则返回false。它的左边是一个字符串,表示属性名,右边是一个对象

    var obj = { p: 1 };
    'p' in obj // true
    'toString' in obj // true
    

      in运算符的一个问题是,它不能识别哪些属性是对象自身的,哪些属性是继承的。

      就像上面代码中,对象obj本身并没有toString属性,但是in运算符会返回true,因为这个属性是继承的。

      这时,可以使用对象的hasOwnProperty方法判断一下,是否为对象自身的属性。

    var obj = {};
    if ('toString' in obj) {
      console.log(obj.hasOwnProperty('toString')) // false
    }
    

    1.2 属性的遍历:for...in 循环

      for...in循环用来遍历一个对象的全部属性。

    var obj = {a: 1, b: 2, c: 3};
    
    for (var i in obj) {
      console.log('键名:', i);
      console.log('键值:', obj[i]);
    }
    // 键名: a
    // 键值: 1
    // 键名: b
    // 键值: 2
    // 键名: c
    // 键值: 3
    

      for...in循环有两个使用注意点。

    • 它遍历的是对象所有可遍历(enumerable)的属性,会跳过不可遍历的属性。
    • 它不仅遍历对象自身的属性,还遍历继承的属性。

      举例来说,对象都继承了toString属性,但是for...in循环不会遍历到这个属性。

    var obj = {};
    
    // toString 属性是存在的
    obj.toString // toString() { [native code] }
    
    for (var p in obj) {
      console.log(p);
    } // 没有任何输出
    

      上面代码中,对象obj继承了toString属性,该属性不会被for...in循环遍历到,

      因为它默认是“不可遍历”的。关于对象属性的可遍历性,参见《标准库》章节中 Object 一章的介绍。

      如果继承的属性是可遍历的,那么就会被for...in循环遍历到。

      但是,一般情况下,都是只想遍历对象自身的属性,所以使用for...in的时候,

      应该结合使用hasOwnProperty方法,在循环内部判断一下,某个属性是否为对象自身的属性。

    var person = { name: '老张' };
    
    for (var key in person) {
      if (person.hasOwnProperty(key)) {
        console.log(key);
      }
    }
    // name
    

    2 with 语句

      with语句的格式如下:

    with (对象) {
      语句;
    }
    

      它的作用是操作同一个对象的多个属性时,提供一些书写的方便。

    // 例一
    var obj = {
      p1: 1,
      p2: 2,
    };
    with (obj) {
      p1 = 4;
      p2 = 5;
    }
    // 等同于
    obj.p1 = 4;
    obj.p2 = 5;
    
    // 例二
    with (document.links[0]){
      console.log(href);
      console.log(title);
      console.log(style);
    }
    // 等同于
    console.log(document.links[0].href);
    console.log(document.links[0].title);
    console.log(document.links[0].style);
    

      注意,如果with区块内部有变量的赋值操作,必须是当前对象已经存在的属性,

      否则会创造一个当前作用域的全局变量。

    var obj = {};
    with (obj) {
      p1 = 4;
      p2 = 5;
    }
    
    obj.p1 // undefined
    p1 // 4
    

      上面代码中,对象obj并没有p1属性,对p1赋值等于创造了一个全局变量p1

      正确的写法应该是,先定义对象obj的属性p1,然后在with区块内操作它。

      这是因为with区块没有改变作用域,它的内部依然是当前作用域。

      这造成了with语句的一个很大的弊病,就是绑定对象不明确。

    with (obj) {
      console.log(x);
    }
    

      单纯从上面的代码块,根本无法判断x到底是全局变量,还是对象obj的一个属性。

      这非常不利于代码的除错和模块化,编译器也无法对这段代码进行优化,

      只能留到运行时判断,这就拖慢了运行速度。

      因此,建议不要使用with语句,可以考虑用一个临时变量代替with

    with(obj1.obj2.obj3) {
      console.log(p1 + p2);
    }
    
    // 可以写成
    var temp = obj1.obj2.obj3;
    console.log(temp.p1 + temp.p2);
    

     

    文章内容转自 阮一峰老师 JavaScript教程 https://wangdoc.com/javascript/index.html

     

  • 相关阅读:
    RecyclerView 数据刷新的几种方式 局部刷新 notify MD
    【图片】批量获取几万张图片
    RV BaseRecyclerViewAdapterHelper 总结 MD
    RecyclerView.ItemDecoration 间隔线
    Kotlin【简介】Android开发 配置 扩展
    Kotlin 特性 语法糖 优势 扩展 高阶 MD
    一个十分简洁实用的MD风格的UI主框架
    折叠伸缩工具栏 CollapsingToolbarLayout
    FloatingActionButton FAB 悬浮按钮
    Glide Picasso Fresco UIL 图片框架 缓存 MD
  • 原文地址:https://www.cnblogs.com/WernerWu/p/11345184.html
Copyright © 2011-2022 走看看