zoukankan      html  css  js  c++  java
  • JavaScript对象的基本用法

    本文主要讲述了:

    • JS对象声明的方法
    • JS对象属性的操作(增删改查)
    • JS对象的遍历方法
    • 以及一些个小区别

    对象是JavaScript的核心概念,也是重要的数据类型,他是JavaScript的其中数据类型(string,number,bool,symbol,null,undefined,object)中唯一一种复杂类型。

    甚么是对象?简单说对象就是“键值对"(无序的数据)的集合。

    var obj = {
      foo: 'Hello',
      bar: 'World'
    };
    

    一、声明对象的方法

    方法一:

    上述代码中大括号就定义了一个对象,并赋值给变量obj,即obj就指向一个对象。该对象内部包含两个键值对(又称成员),一个键值对是foo:'Hello',其中foo是键名(成员名称),字符串Hello是键值(成员值),键名和键值之间用冒号分隔。第二个键值对是bar:'World',同上。两个键值对之间用逗号隔开。

    对象的所有键名都是字符串(ES6中的Symbol也可以作为键名),所以不加引号也可以(会将其认为是字符串),所以上述声明对象的方式还可以写成这样:

    var obj = {
      'foo': 'Hello',
      'bar': 'World'
    };
    

    当然如果键名不符合标识名的条件就必须加上引号:

    //报错
    var obj = {
      1p: 'Hello World'
    };
    //不报错
    var obj = {
      '1p': 'Hello World',
      'h w': 'Hello World',
      'p+q': 'Hello World'
    };
    

    方法二:

    利用new创建对象:

    let obj = new Obj({ name:'arleen; age:18' })
    

    对象的属性名又被称作属性(property),他的键值可以是任何数据类型,包括方法。对象的属性是可以动态创建的,不需要再创建对象的时候就指定。

    关于对象的疑问

    对象采用大括号表示,这导致了一个问题,如果行首是一个大括号,他到底是表示表达式(视为对象)还是语句(代码块):

    { foo: 123 }
    

    JavaScript 引擎读到上面这行代码,会发现可能有两种含义。第一种可能是,这是一个表达式,表示一个包含foo属性的对象;第二种可能是,这是一个语句,表示一个代码区块,里面有一个标签foo,指向表达式123

    为了避免这种歧义,JavaScript 引擎的做法是,如果遇到这种情况,无法确定是对象还是代码块,一律解释为代码块。

    { console.log(123) } // 123
    

    上面的语句是一个代码块,而且只有解释为代码块,才能执行。

    如果要解释为对象,最好在大括号前加上圆括号。因为圆括号的里面,只能是表达式,所以确保大括号只能解释为对象。

    ({ foo: 123 }) // 正确
    ({ console.log(123) }) // 报错
    

    二、属性的操作

    2.1属性的读取

    • 读取一个属性

    读取对象属性的方法有两种,一种是使用点运算符,一种是使用方括号运算符。

    var obj = {
      p: 'Hello World'
    };
    
    obj.p // "Hello World"
    obj['p'] // "Hello World"
    

    这里需要注意的是点运算符后面可以是标识符可以是字符串,但是[]方括号运算符里面的键名必须放在引号里面,否则会被当作变量来处理(会计算出变量的结果再将其转化为字符串);

    var foo = 'bar';
    
    var obj = {
      foo: 1,
      bar: 2
    };
    
    obj.foo  // 1
    obj[foo]  // 2
    
    • 读取对象的所有属性(Object.keys(obj) 不包括原型上的共有属性)
    let obj = {
      name:'lianghonglei',
      age:18
    }
    console.log(Object.keys(obj))//
      age:18
    }
    console.log(Object.keys(obj))//["name", "age"]
    
    • 读取对象所有的值(Object.values(obj))
    let obj = {
      name:'lianghonglei',
      age:18
    }
    console.log(Object.values(obj))//["lianghonglei", 18]
    
    • 读取对象所有键值对(Object.entries(obj))
    let obj = {
      name:'lianghonglei',
      age:18
    }
    console.log(Object.entries(obj))//[["name", "lianghonglei"], ["age", 18]]
    
    • 读取对象的所有属性,包括_proto_

    需要注意的是在读取对象上的属性的时候,如果对象本身上并不存在改属性,那么会顺着原型链去查找;但相反,在修改或增加对象的属性的时候,不会按着原型链查找,而是直接作用在对象本身上。

    • 判断一个属性是对象自身属性还是原型上的共有属性

    如果是对象本身的属性返回true,如果是原型上的属性返回false.

    补充:'name' in obj和obj.hasOwnProperty('name') 的区别

    in不能区分name是obj原型上的属性还是自身的属性,他只能查看obj是否存在改属性,但无法辨别,而hasOwnProperty只有在属性是obj自身上的时候才会返回true。

    2.2 属性的赋值、修改和增加(写属性)

    点运算符和方括号运算符不仅可以用来读取值,还可以用来赋值:

    var obj = {}
    obj.foo = 'hello';
    obj['bar'] = 'world';
    

    修改:

    var obj = {
        name:'lianghonglei',
        age:18
    }
    obj.name = 'arleen';//修改姓名为arleen
    obj['age'] = 20;//修改年龄为30
    

    这里修改的都是obj本身的属性,但是如果我们想要修改obj原型(obj.__proto_)上的属性怎么办?

    直接obj._proto_.toString = 'xxx'是可以的,但是我们不建议这么做,obj._proto_ 相当于 window.Object.prototype,所以我们可以借助后者去修改。但即使是这样,我们是不建议去修改原型上的共有属性的,因为这会引起很多问题。

    可以这样做:

    // 创建自己的原型(就可以不用去修改原来的原型了)Object.create
    var common = {'国籍':'中国'}
    var person = Object.create(common)
    

    增加:

    var obj = {
        name:'lianghonglei',
        age:18
    }
    obj.idol = 'tom hiddleston'; //添加属性idol
    obj['reading'] = '白夜行'; // 添加属性reading

    如果要批量赋值(一次赋值好多个属性)Object.assign(obj,{需要添加的成员们})

     

    2.3 属性的删除

    delete命令用域删除对象的属性(即属性名和属性值一并删除),删除成功之后返回true。

    注意,删除一个不存在的属性,delete不会报错,且返回true。所以我们不能根据delete命令的返回结果去判定一个属性是不是存在。

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

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

    var obj = Object.defineProperty({}, 'p', {
      value: 123,
      configurable: false//设置为p属性不得修改
    });
    
    obj.p // 123
    delete obj.p // false
    

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

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

    上面代码中,toString是对象obj继承的属性,虽然delete命令返回true,但该属性并没有被删除,依然存在。这个例子还说明,即使delete返回true,该属性依然可能读取到值。

    2.4 属性是否存在

    in运算符用于检查对象是否包含某个属性(注意,检查的是键名,不是键值),如果包含就返回true,否则返回false。它的左边是一个字符串,表示属性名,右边是一个对象。

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

    in运算符的一个问题是,它不能识别哪些属性是对象自身的,哪些属性是继承的。就像上面代码中,对象obj本身并没有toString属性,但是in运算符会返回true,因为这个属性是继承的。

    这时,可以使用对象的hasOwnProperty方法判断一下,是否为对象自身的属性。(上面已经提到过hasOwnProperty)

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

    2.5 属性的遍历

    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
  • 相关阅读:
    nginx的location root 指令
    nginx系统真正有效的图片防盗链完整设置详解
    HttpURLConnection请求接口
    Tomcat:IOException while loading persisted sessions: java.io.EOFException解决手记
    jprofiler安装图解及破解码
    养成好的JAVA编码习惯
    JS函数(自调函数)与闭包【高级函数】
    Java基础加强-(注解,动态代理,类加载器,servlet3.0新特性)
    Intent显示启动与隐式启动
    JSP中四种传递参数的方法
  • 原文地址:https://www.cnblogs.com/browser/p/14401189.html
Copyright © 2011-2022 走看看