• js对象


    在前面,我们有介绍过,在JavaScript中,数据类型整体上来讲可以分为两大类:简单数据类型 和复杂数据类型。

    简单数据类型一共有6种,分别是我们前面介绍过的

    string , number , boolean , null , undefined 以及本章将会介绍的 symbol

    而复杂数据类型就只有1种

    object

    也就是我们本章将会向大家所介绍的对象。事实上,我们前面已经遇到过一些对象了。例如之前 所介绍过的数组就是一种对象,不过它是JavaScript语言中内置的对象。在本章中我们将学习到 如何自定义对象,以及一些其他的内置对象。

    本章将学习如下内容:

    ・创建对象的方式

    ・访问对象属性的方式

    ・对象常用的属性和方法

    ・对象的嵌套与解构

    • this关键字

    ・JSON对象

    • Math对象
    • Date对象

    •正则表达式

    6-1对象基础介绍

    6-1-1 JS对象概述

    JavaScript里面的对象就是一组键值对的集合。这些键一般由字符串构成,而值可以是任意数据 类型。比如字符串,数字,布尔,数组或者函数。一般来讲,如果一个键映射的是一个非函数的 值,我们将这个值称之为该对象的属性,而如果一个键映射的是一个函数的值,那么我们将其称 之为方法。

    6-1-2创建对象

    要创建一个对象,我们只需要输入一对大括号即可。这样我们就可以创建一个空的对象,如下:

    let objName = {};

    创建好对象以后,我们就可以给该对象添加相应的属性,例如这里我们给xiejie这个对象添加 相应的属性

    let xiejie = {};

    xiejie.name = "xiejie";

    xiejie.age = 18;

    xiejie.gender = "male";

    xiejie.score = 100;

    当然,和前面为大家介绍过的数组一样,我们可以在创建对象时就给对象添加好属性信息,如 下:

    let xiejie = {

    name : "xiejie",

    age : 18,

    gender : "male",

    score : 100

    };

    可以看到,当我们创建包含属性的对象的时候,属性与属性之间是以逗号隔开的。这里我们可以 将属性名称之为键,属性对应的称之为值。所以,正如开头我们所介绍的那样,对象是由一个一 个键值对组成的。

    6-1-3访问对象属性

    访问对象的属性的方法有3种:点访问法,中括号访问法,symbol访问法

    1. 点访问法

    我们可以通过一个点.来访问到对象的属性,如下:

    let xiejie = {

    name : "xiejie",

    age : 18,

    gender : "male",

    score : 100

    };

    console.log(xiejie.name);//xiejie

    console.log(xiejie.age);//18 console.log(xiejie.gender);//rnale

    console.log(xiejie.score);//100

    1. 中括号访问法

    第二种方法,是使用中括号法来访问对象的属性,如下:

    let xiejie = {

    name : "xiejie",

    age : 18,

    gender : "male",

    score : 100

    };

    console.log(xiejie["name"]);//xiejie console.log(xiejie["age"]);//18

    console.log(xiejie["gender"]);//male console.log(xiejie["score"]);//100

    —般来讲,访问对象属性的时候使用点访问法的情况要多一些,那什么时候使用中括号访问方法 呢?当我们的属性名来自于变量的时候,这个时候中括号就要比点要灵活许多。来看下面的例 子:

    let xiejie = {

    name : "xiejie",

    age : 18,

    gender : "male",

    score : 100

    };

    let str = "name"; console.log(xiejie[str]);//xiejie

    既然讲到了对象属性的中括号访问法,那我们就顺带介绍一下伪数组对象的原理。前面给大家介 绍过的argument s就是一个伪数组对象。伪数组对象的原理就在于对象的键都是数字。如果属性 名是数字的话,通过中括号法来访问时可以不用添加引号,如下:

    let obj = {

    1 : "Bill",

    2 : "Lucy",

    3 : "David"

    }

    console.log(obj[1]);//Bill

    console.log(obj[2]);//Lucy

    console.log(obj[3]);//David

    这样,就形成了给人感觉像是数组,但是并不是数组的伪数组对象。

    1. symbol访问法

    在ES6之前,对象的属性名都只能是字符串。但是这样很容易造成属性名的冲突。比如我们使用 了一个别人提供的对象,然后我们想在这个对象的基础上进行一定的扩展,添加新的属性,这个 时候由于并不知道原来的对象里面包含哪些属性名,所以很容易就把别人的对象所具有的属性给 覆盖掉了。示例如下:

    //假设person对象是从外部库引入的一个对象

    let person = {

    name : "xiejie"

    }

    console.log(person.name);//xiejie

    person.name = "yajing"; console.log(person.name);//yajing

    可以看到,这里两个name就产生了冲突,下面的name就把上面的name给覆盖掉了。

    从ES6开始,新增了symbol这种数据类型,专门来解决这样的问题。创建symbol,需要使 Symbol。函数,其语法如下:

    let sym = Symbol(描述信息);

    示例:

    let name = Symbol("这是一个名字");

    console.log(name);//Symbol(这是一个名字) console.log(typeof name);//symbol

    这里的描述信息是可选的,是对我们自己创建的symb。l的一个描述。接下来我们来用symb。l 为对象的属性,示例如下:

    let person = {

    name : "xiejie"

    }

    let name = Symbol("这是一个名字");

    person[name] = "yajing";

    console.log(person.name);//xiejie console.log(person[name]);//yajing

    可以看到,使用symbol来作为对象的属性,避免了同名的属性名发生冲突。

    有些时候我们希望在不同的代码中共享一个symbol,那么这个时候可以使用Symbol.for()方法 来创建一个共享的symbol。ES6提供了一个可以随时访问的全局symb。l注册表。当我们使 Symbol.for()方法注册一个symbo l的时候,系统会首先在全局表里面查找对应的参数的 symbol是否存在,如果存在,直接返回已经有的symbol,如果不存在,则在全局表里面创建一 个新的symbol

    let obj = {};

    let name = Symbol.for("test");

    obj[name] = "xiejie";

    let name2 = Symbol.for("test"); console.log(obj[name2]);//xiejie

    如果使用Symbol.for()方法创建symbo l的时候没有传递任何参数,那么也会将undefined作为 全局表里面的键来进行注册,证明如下:

    let obj = {};

    let name = Symbol.for();

    obj[name] = "xiejie";

    let name2 = Symbol.for(undefined); console.log(obj[name2]);//xiejie

    ES6里面还提供了 Symbol.keyFor()方法来查找一个symbo l的键是什么。但是需要注意的是, 该方法只能找到注册到全局表里面的symbol的键。如果是通过Symbol。方法创建的symbol, 无法找到的。这其实也很好理解,通过Symbol()方法创建的symbo l都不存在有键。

    let obj = {};

    let name1 = Symbol("test1");

    let name2 = Symbol.for("test2");

    let i = Symbol.keyFor(namel);

    let j = Symbol.keyFor(name2);

    console.log(i);//udnefined console.log(j);//test2

    前面有提到,如果一个对象的属性对应的是一个函数,那么这个函数被称之为对象的方法。访问 对象方法的方式和上面介绍的访问对象属性的方式是一样的,可以通过点访问法,中括号访问法 以及symbo l访问法来进行对象方法的调用。

    let walk = Symbol("this is a test"); let person = {

    name : "xiejie", walk : function(){ console.log("I'm walking");

    },

    [walk] : function(){ console.log("I'm walking,too");

    }

    }

    person.walk();//I'rn walking person["walk"]();//I'm walking person[walk]();//I'm walking,too

    6-1-4删除对象属性

    对象的任何属性都可以通过delete运算符来从对象中删除。示例如下:

    let person = {

    name : "xiejie",

    age : 18,

    walk : function(){

    console.log("I'm walking");

    }

    }

    console.log(person.age);//8

    delete person.age;//删除age 这个属性

    console.log(person.age);//undefined

    person.walk();//I'm walking

    delete person.walk; //删除walk方法 person.walk();//指错

    //TypeError: person.walk is not a function

    如果是删除的是属性,那么再次访问值为变为undefined,而如果删除的是方法,那么调用时会 直接报错

    6-1-5对象常用属性和方法

    1. in操作符

    该操作符用于判断一个对象是否含有某一个属性,如果有返回true,没有返回false。需要注意的 是目前为止还无法判断对象的symb。l属性的包含情况,如果属性是symbol,那么会直接报错

    let person = {

    name : "xiejie",

    age : 18,

    walk : function(){

    console.log("I'm walking");

    }

    }

    let gender = Symbol("person's gender");

    person[gender] = "male";

    console.log("name" in person);//true console.log("age" in person);//true console.log([gender] in person);//灰错

    //TypeError: Cannot convert a Symbol value to a string

    但是需要注意,虽然上面给出了无法转换的错误,不过如果我们按照下面的方式来查看的话,是

    会返回true的

    let person = {

    name : "xiejie",

    age : 18,

    walk : function(){

    console.log("I'm walking");

    }

    }

    let gender = Symbol("person's gender");

    person[gender] = "male"; console.log("name" in person); // true console.log("age" in person); // true console.log(gender in person); // true

    2. for..in

    这个for..in我们在前面讲解遍历数组的时候已经见到过了。可以使用for..in来取出数组的键。除此 之外,我们还可以使用for..in来循环遍历一个对象的所有属性,示例如下:

    let person = {

    name : "xiejie",

    age : 18,

    walk : function(){

    console.log("I'm walking");

    }

    }

    for(let i in person){

    console.log(i);

    }

    // name

    // age

    // walk

    需要注意的是,使用for..in虽然说可以遍历出一个对象的所有的属性和方法(包括继承的,关于继 承后面会介绍),但是无法遍历出用symbol来定义的属性,证明如下:

    let person = {

    name : "xiejie",

    age : 18,

    walk : function(){

    console.log("I'm walking");

    }

    }

    let gender = Symbol("person's gender");

    person[gender] = "male";

    for(let i in person){

    console.log(i);

    }

    // name

    // age

    // walk

    那么,这个时候可能有人会问了,那我如何才能遍历出一个对象的s ymbo l属性呢?这里介绍两种 方式。

    第一种是使用Object.getOwnPropertySymbols()来返回一^对象所有的symbo l属性,如下:

    let person = {

    name : "xiejie",

    age : 18,

    walk : function(){

    console.log("I'm walking");

    }

    }

    let gender = Symbol("person's gender");

    person[gender] = "male";

    console.log(Object.getOwnPropertySymbols(person));

    //[ Symbol(person's gender)]

    除了上面的方法以外,ES6中还提供了一个叫做Reflect.ownkeys()方法。该方法可以遍历出 —个对象的所有类型的键名,包括字符串的键名以及symbo l键名

    let person = { name : "xiejie",

    age : 18,

    walk : function(){

    console.log("I'm walking");

    }

    }

    let gender = Symbol("person's gender"); person[gender] = "male";

    console.log(Reflect.ownKeys(person));

    //[ 'name', 'age', 'walk', Symbol(person's gender)]

    3. keys。,values。,entries

    前面在介绍遍历数组,集合以及映射的时候,有介绍过这3个方法,分别用于找出可迭代对象的 键,值,以及键和值。实际上,我们的对象也是属于可迭代对象的一种,所以也可以使用这3 方法来找出对象的键和值

    Object.keyO

    let person = {

    name : "xiejie",

    age : 18,

    walk : function(){

    console.log("I'm walking");

    }

    }

    let gender = Symbol("person's gender"); person[gender] = "male";

    for(let i of Object.keys(person)){

    console.log(i);

    }

    // name

    // age

    // walk

    Object.valuesO

    let person = { name : "xiejie", age : 18,

    walk : function(){

    console.log("I'm walking");

    }

    let gender = Symbol("person's gender"); person[gender] = "male";

    for(let i of Object.values(person)){ console.log(i);

    }

    // xiejie

    // 18

    // [Function: walk]

    Object.entriesO

    let person = { name : "xiejie", age : 18,

    walk : function(){

    console.log("I'm walking");

    }

    }

    let gender = Symbol("person's gender"); person[gender] = "male";

    for(let i of Object.entries(person)){ console.log(i);

    }

    // [ 'name', 'xiejie' ]

    // [ 'age', 18 ]

    // [ 'walk', [Function: walk] ]

    6-1-6嵌套对象

    —个对象里面可以包含其他的对象,这个我们称之为对象的嵌套。示例如下:

    let family = { xiejie : {

    age : 18,

    gender : "male"

    },

    song : {

    age : 20,

    gender : "female"

    }

    };

    当我们访问嵌套对象里面的值的时候,和访问单个对象的方式是一样的。

    let family = {

    xiejie : {

    age : 18, gender : "male"

    },

    song : {

    age : 20, gender : "female"

    }

    };

    console.log(family.xiejie.gender);//male 点访问法 console.log(family["song"]["age"]);//20 中括号访问法

    对象的解构

    在前面介绍解构的时候,我们有介绍过数组的解构。实际上对象我们也是可以将其解构的。解构 的方式也是和解构数组是类似的,示例如下:

    let a = {name:"xiejie",age:18};

    let b = {name:"song",age:20};

    let {name:aName,age:aAge} = a; let {name:bName,age:bAge} = b; console.log(aName);//xiejie console.log(aAge);//18 console.log(bName);//song console.log(bAge);//20

    当属性名和变量名一致的时候,可以进行简写,示例如下:

    let a = {name:"xiejie",age:18};

    let {name,age} = a;

    console.log(name);//xiejie console.log(age);//18

    和数组一样,同样可以解构嵌套的对象,如下:

    let family = { xiejie : {

    age : 18, gender : "male"

    },

    song : {

    age : 20,

    gender : "female"

    }

    };

    let {xiejie,song} = family;

    console.log(xiejie);//f age: 18, gender: 'male' } console.log(song);//f age: 20, gender: 'female' }

    顺便一提的是,解构我们也是可以像函数一样设置一个默认值的,这里一起来看一下,如下:

    let {name="xiejie",age} = {}; console.log(name);//xiejie console.log(age);//undefined

    这里我们为name变量设置了一个默认值为xiejie,当我们解构一个空对象的时候,name变量的值 就使用了默认的xiejie这个值,而age这个变量由于没有设置默认值,所以值为undefined。

    当然,既然叫做默认值,和函数一样,如果有解构的值传过来的话,肯定就是使用解构传过来的 值,如下:

    let {name="xiejie",age} = {name:"song",age:10}; console.log(name);//song console.log(age);//10

    6-1-7对象作为函数参数

    对象字面量也可以作为函数的参数进行传递。这在有很多形式参数的时候非常有用,因为它允许 我们在调用函数时不用记住参数的顺序。

    我们先来看一下我们一般函数调用的例子,如下:

    let test = function(name,age){

    console.log('我叫${name},我今年${age}');

    }

    test("xiejie", 18);//我叫xiejie,我今年 18 test(18,"xiejie");//我叫 18,我今年xiejie

    可以看到,以前我们调用函数传递参数时,参数的顺序是必须要和形式参数的顺序一致的。否则 就会出现上面第2次调用函数的情况,输出不符合预期的结果。

    当我们使用对象字面量来最为形式参数时,就可以不用按照定义函数时形式参数的顺序,只要名 字相同即可,如下:

    let test = function({name,age}){

    console.log('我叫${name},我今年${age}');

    }

    test({name:"xiejie",age:18});我今年 18  test({age:18,name:"xiejie"});//^^AXiejie,我今年 18

    可以看到,只要参数名能对上号,位置是可以随意放置的。

    和前面介绍函数的参数默认值一样,当对象字面量作为参数的时候,我们也可以为字面量的每一 项设置一个默认值,甚至我们还可以给整个对象字面量一个默认值,示例如下:

    //给整个对象字面量一个默认值{ name:"BilT,age:20}

    let test = function({name = "xiejie",age = 18} = {name:"Bill",age:20}){ console.log('我叫${name},我今年${age}');

    }

    test();//我叫Bill,我今年20

    test({});//我叫xiejie,我今年 18 test({name:"yajing"});//我〃V/ajing,我今年 18  test({age:1,name:"xizhi"});//我〃AXizhi,我今年 1

    这种技术被称之为命名参数,经常被用在函数有很多可选参数的时候。

    6-1-8 this关键字

    既然学习到了对象,那么有必要介绍一下this关键字。this ,翻译成中文就是这个的意思。 当我们在一个对象中使用this关键字时,该关键字就代表的是当前对象。来看下面的例子:

    let person = {

    name : 'xiejie',

    age : 18,

    intro : function(){

    console.log(this);

    // { name: 'xiejie', age: 18, intro: [Function: intro] } console.log('My name is ${this.name},I'm ${this.age} years old'); // My name is xiejie,I'm 18 years old

    }

    }

    person.intro();

    这里我们调用了 person对象的intro方法,里面涉及到了 this关键字。由于是在对象里面,所 this指向当前对象,也就是person这个对象。所以this.name等价

    person.name , this.age 等价于 person.age。

    6-1-9命名空间(扩展)

    当相同的变量和函数名被共享在同一作用域的时候,就会发生命名冲突。这看起来不太可能,但 是我们可以想象一下,随着时间的推移,我们已经写了很多的代码,可能不知不觉就重用了一个 变量名。如果是使用的其他开发者的代码库,这种问题就变得更加有可能。

    解决命名冲突的方式,就是使用对象字面量来为一组相关函数创建一个命名空间。这样在调用这 些函数的时候需要先写上对象名,这里的对象名就充当了命名空间的角色。示例如下:

    let myMaths = {

    //求平方函数

    square : function(x){

    return x * x;

    },

    //传入数组求平均值函数

    avg : function(arr){

    let total = arr.reduce((a,b) => a + b);

    return total / arr.length;

    }

    }

    let arr = [1,2,3,4,5];

    console.log(myMaths.avg(arr));//3

    console.log(myMaths.square(5));//25

    这里我们的myMaths就是我们的命名空间,这样就不用担心和其他人的变量或者函数名发生命 名冲突。

  • 相关阅读:
    docker部署mysql
    jira+mysql+破解+中文+compose
    swarm 服务器安装
    docker
    mysql创建用户并手授权
    统计数据库表容量情况
    分区表测试
    实战做项目如何选择开源许可协议(一)-了解协议
    创业公司如何实施敏捷开发
    技术人员如何创业《四》- 打造超强执行力团队
  • 原文地址:https://www.cnblogs.com/dazhongma/p/11400555.html
Copyright © 2020-2023  润新知