ES语法(三)

1.Promise**

1.概念

​ Promise 是异步编程的一种解决方案,比传统的回调函数和事件更合理、更强大。Promise是一个构造函数, 用来生成Promise实例, Promise实例是异步操作管理者。Promise代表了未来某个将要发生的事件(通常是一个异步操作) ,可以将异步操作以同步的流程表达出来, 避免了层层嵌套的回调函数(回调地狱)
Promise本身还是在使用回调函数(只不过比回调函数多了一种状态管理)

2.使用

​ 创建promise对象,实例化Promise 参数是回调函数,内置两个参数,resolve和reject

1.promise三个状态

​ 初始化状态 pending

​ 成功状态 fullfilled

​ 失败状态 rejected

2.调用

​ then : 触发resolve方法执行then

let promise = new Promise((resolve,reject)=>{
    // 初始化状态
    let num = 10;
    // 判定
    if (num > 10){
        resolve('成功');
    }else{
        reject('失败');
    }
})// 使用promise对象中的then方法进行触发promise对象
// then方法内置一个或者两个参数  如果是一个参数  
// 第一个参数  是resolve函数  是一个回调函数
// 第二个参数  可选  是reject函数   是一个回调函数
// 返回值是一个新的promise
let a = promise.then(data=>{
    console.log(data);
},err=>{
    console.log(err);
})
console.log(a);

​ catch : 触发reject方法执行catch

let promise = new Promise((resolve,reject)=>{
    let num = 10;
    if (num > 100){
        resolve('成功');
    }else{
        console.log(alsdjla);
        reject('失败');
    }
})
promise.then(data=>{
    console.log(data);
}).catch(error=>{
    console.log(error);
})

3.捕获异常

​ 在使用then的时候是无法捕获异常的 但是在catch中可以捕获异常

​ try : 可能出现异常的代码

​ catch : 如果try出现错误,代码执行catch

​ finally : 不管会不会发生异常,都会执行finally中的代码

try{
    console.log(num);
}catch{
    let num = 500;
    console.log(num);
}finally{
    console.log('gameover');
}

4.链式操作

​ then方法的第一个参数,成功时的回调函数,分两种情况

​ 返回了一个普通的数据(非promise),这个值会作为参数传递给下一个then的成功回调

​ 返回了一个promise,下一个then的执行,取决于这个promise状态的改变

let promise = new Promise((resolve,reject)=>{
    let num = 10;
    if (num > 5){
        resolve('获取京东首页');
    }else{
        reject('404页面走丢了');
    }
})

// 触发Promise
promise.then(data=>{
    console.log(data);
    return data + '中的一级栏目';
}).then(data=>{
    console.log(data);
    return data + '中的二级栏目';
}).then(data=>{
    console.log(data);
    return data + '中的浪琴';
}).then(data=>{
    console.log(data);
})
all方法

​ all方法是Promise中的静态方法 不需要实例化Promise 就可以直接使用

​ 它主要的作用是执行所有的Promise 也就是说 一次性可以执行多个Promise

let p1 = new Promise((resolve,reject)=>{
    setTimeout(() => {
        resolve('这是p1');
    }, 2000);
})

let p2 = new Promise((resolve,reject)=>{
    setTimeout(() => {
        resolve('这是p2');
    }, 3000);
})

let p3 = new Promise((resolve,reject)=>{
    setTimeout(() => {
        resolve('这是p3');
    }, 1000);
})

// 使用Promise构造中的all方法  内置一个参数  参数是一个数组  数组中每一个元素都是一个Promise
let p = Promise.all([p1,p2,p3]);
p.then(d=>{
    console.log(d);
})
race方法

​ race方法是Promise中的静态方法 不需要实例化Promise 就可以直接使用

​ 执行速度最快的那个Promise 其他的都不执行

let p1 = new Promise((resolve,reject)=>{
    setTimeout(() => {
        resolve('这是p1');
    }, 2000);
})

let p2 = new Promise((resolve,reject)=>{
    setTimeout(() => {
        resolve('这是p2');
    }, 3000);
})

let p3 = new Promise((resolve,reject)=>{
    setTimeout(() => {
        resolve('这是p3');
    }, 1000);
})

// race方法  执行最快的Promise   内置一个参数  参数是一个数组  数组中的每一个元素都是Promise
let p = Promise.race([p1,p2,p3]);
p.then(d=>console.log(d));

2.async…await函数**

1.目的

​ 真正意义上去解决异步回调的问题,同步流程表达异步操作

​ 本质上async 是 Generator和Promise的语法糖

2.特点

​ 不需要像Generator去调用next方法,遇到await等待,当前的异步操作完成就往下执行

​ 被async修饰的函数,是一个异步函数 返回的总是Promise对象,可以用then方法进行下一步操作

​ async取代Generator函数的星号*,await取代Generator的yield

​ 语意上更为明确,使用简单,经临床验证,暂时没有任何副作用

async…await特点*

1.async修饰的函数可以使用await 其他函数不可以使用 即使使用 也没有效果
​ 2.async函数 无论函数内容是什么 返回值都是一个promise
​ 3.await会自动获取我们async函数中的promise对象中的resolve状态 并且经过异常处理
​ 4.他会将我们异步代码变成同步代码进行执行

3.案例

function fn1(){
    return new Promise((resolve,reject)=>{
        setTimeout(() => {
            // console.log('fn1');
            resolve('这是fn1  执行事件为2s');
        }, 2000);
    })
}

function fn2(){
    return new Promise((resolve,reject)=>{
        setTimeout(() => {
            // console.log('fn2');
            resolve('这是fn2  执行事件为2s');
        }, 3000);
    })
}

function fn3(){
    return new Promise((resolve,reject)=>{
        setTimeout(() => {
            // console.log('fn3');
            resolve('这是fn3  执行事件为1s');
        }, 1000);
    })
}
async function fn(){
    let v1 = await fn1();
    console.log(v1);
    let v2 = await fn2();
    console.log(v2);
    let v3 = await fn3();
    console.log(v3);
}
fn();

3.面向对象

​ 什么是面向过程 : 需要什么写什么 需要什么封装什么

​ 什么是面向对象 : 就是 我们将一系列的程序 逻辑 代码 进行封装 需要的时候 直接调用

​ 面向对象的优势

​ 减少代码冗余

​ 便于后期维护

​ 保证数据安全

1.类和对象的关系

​ 类是对象的抽象 对象是类的具体

​ 类是对象的模板 对象是类的铸件

2.类的成员

​ 成员属性 : 类似于变量 但是不同于变量 成员属性在类中是全局的 属性是一个事务的特征 特性

​ 成员方法 : 类似于函数 但是不同于函数 成员方法在类中是全局的 方法指的是一个事物的行为

​ 定义一个类 使用关键字 class 后面是类名 类名后面直接跟上大括号 没有形参列表

​ 类名的命名一般使用帕斯卡命名法

3.实例化一个类

​ 实例化一个对象 使用关键字 new

// 定义一个类
class Car{
    // 定义成员属性
    name = 'Audi';
    color = "black";

    // 定义成员方法
    start(){
        console.log(this.name + '车启动了');
    }
}

// 实例化一个对象
let c = new Car();
console.log(c.name);
console.log(c.color);
c.start();

4.构造器

​ 构造器是每一个类中都存在的方法 即使你不定义 他也存在

​ 构造方法是魔术方法 不需要调用 在满足条件的情况下会被自动调用

​ 构造方法 只要实例化了一个对象 就会被自动调用

​ 主要的作用是用来初始化对象使用

​ 构造器关键字 : constructor

class Person{
    constructor(name,age,sex) {
        this.name = name;
        this.age = age;
        this.sex = sex;
    }

    say(){
        console.log(`我的名字叫做${this.name},我是一个${this.age}岁的${this.sex}孩`);
        console.log(this.food);
    }

    eat(food){
        this.food = food;
    }

}

let obj = new Person('Eric',18,'男');
obj.say();

let newObj = new Person('Mary',13,'女');
newObj.eat('套餐');
newObj.say();
class Person{
    constructor(name,age,sex) {
        this.name = name;
        this.age = age;
        this.sex = sex;
    }

    say(){
        console.log(`我的名字叫做${this.name},我是一个${this.age}岁的${this.sex}孩`);
    }

}
let obj = new Person('Eric',18,'男');
obj.say();

let newObj = new Person('Mary',13,'女');
newObj.say();

5.继承

​ 继承就是一个类中有另一个类的方法和属性 这就是继承
​ 可以减少代码的冗余

​ 继承 使用关键字 extends

// 定义一个父类  也就基类
class Worker{
    constructor(name){
        this.name = name;
    }

    zb(){
        console.log(this.name + '的周报');
    }

    jx(){
        console.log(this.name + '的绩效');
    }

}

// 子类  或者叫做派生类   继承父类
class Boss extends Worker{
    // 定义子类的方法
    szb(){
        console.log(this.name + '审核周报');
    }
    sjx(){
        console.log(this.name + '审核绩效');
    }
}

let w = new Worker('Eric');
w.zb();
w.jx();


let b = new Boss('Mary');
b.jx();
b.zb();
b.sjx();
b.szb()

6.方法的重写

​ 当我们父类中的方法 不能满足子类的需求的时候 我们可以对父类的方法进行重写 或者覆盖

// 定义一个父类  也就基类
class Worker{
    constructor(name){
        this.name = name;
    }

    zb(){
        console.log(this.name + '的周报');
    }

    jx(){
        console.log(this.name + '的绩效');
    }

}

// 子类  或者叫做派生类   继承父类
class Boss extends Worker{
    // 定义子类的方法
    szb(){
        console.log(this.name + '审核周报');
    }
    sjx(){
        console.log(this.name + '审核绩效');
    }
    // 直接定义重名方法  覆盖父类的方法
    jx(){
        console.log(this.name + '说  我是按照季度发放奖金的');
    }
}

let w = new Worker('Eric');
w.jx();

let b = new Boss('Mary');
b.jx();

7.继承构造器

​ 如果说构造器不能满足我们子类的需求 那么我们怎么班

​ 构造器不能直接重写 不能覆盖 不能自己重新定义

​ 我们重写构造器的时候 需要先继承父类的构造器 并且继承父类构造器中所有的参数

​ 继承构造器 我们需要使用super关键字

class Worker{
    constructor(name){
        this.name = name;
    }
    jx(){
        console.log(this.name + '的绩效');
    }
}

class Boss extends Worker{
    constructor(name,money){
        super(name);
        this.money = money;
    }
    sjx(){
        console.log(this.name + '审核绩效');
    }
    jx(){
        console.log(this.name + "说  我的工资至少一个月" + this.money);
        console.log(this.name + '说  我是按照季度发放奖金的');
    }
}

let b = new Boss('三哥',80000);
b.jx();

8.静态方法

​ 静态方法其实就像Promise中的all方法或者是race方法一样 不需要实例化 直接能够调用的方法

​ 静态方法需要使用static进行修饰 它不存储在我们传统对象的堆栈空间中 他存储在数据段 对每一个空间都进行开放

​ 不需要实例化 没有引用 所以说 我们静态方法执行的效率比较快 大约比普通方法快55%

​ 调用静态方法 类名.方法()

class Person{
    constructor(name,age) {
        this.name = name;
        this.age = age;
    }

    say(){
        console.log(this.name + "不说实话  说他只有" + this.age + "岁");
        console.log(this);
    }

    // 定义静态方法
    static eat(){
        // console.log('今天中午吃点饭');
        console.log(this.name + '今天中午吃点饭');
    }
}
let p = new Person('Eric',18);
// console.log(p);
// p.say()

// Person.say();

// 调用静态方法
// Person.eat();
Person.eat();
// p.eat();

注意 静态方法中 不能有非静态成员

4.ES6模块

1.概念

什么是模块 模块其实就是我们JS文件或者是一个JSON
​ 模块打包一共分为两个部分

​ 第一部分 : 引入 在ES6中 引入使用import … from

​ 第二部分 : 暴露 在ES6中 暴露使用export

2.暴露

​ 暴露 : 其实就是模块中向外部展示的数据

​ 如果说模块中的数据没有暴露 那么是不能被其他程序进行引入的

3.引入

​ 引入 : 引入某个模块的程序 如果不引入 那么不能使用

注意事项

​ 第一 : 引入的时候 script标签中 一定要加上一个属性 type=“module”

​ 第二 : 程序必须在服务器上运行 使用IP或者域名进行访问

let name = 'Eric';
let age = 18;
let sex = '男';
let username = 'admin';
let password = "123";

let arr = [11,22,33];

let fun = ()=>{
    console.log('这是一个函数');
}

let obj = {name,age,sex}

export {
    username,
    password,
    arr,
    fun,
    obj,
	name,
	age,
	sex
}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    
</body>
</html>
<script type="module">
import {username,password,obj,name,age,sex} from "./8.js";
console.log(username);
console.log(password);
console.log(obj);
console.log(name);
</script>

5.字符串扩展

​ includes : 是否包含字符串

​ startsWith : 是否以某个字符开头

​ endsWith : 是否以某个字符结尾

​ repeat : 重复字符串指定的次数

// includes  :  是否包含字符串  检测自付出中是否包含某个字符或者字符串
let str1 = 'hello';
console.log(str1.includes('h'));
console.log(str1.includes('l'));
console.log(str1.includes('el'));
console.log(str1.includes('lll'));

// repeat  :  重复字符串指定的次数  参数是重复的次数
let str = '*';
console.log(str.repeat(60));
// console.log(str.repeat(6));

// startsWith  :  是否以某个字符开头
let str2 = "http://www.ujiuye.com";
console.log(str2.startsWith('http://'));
console.log(str2.startsWith('https://'));
console.log(str.repeat(60));


// endsWith  :  是否以某个字符结尾
let str3 = "http://www.ujiuye.com/index.html";
console.log(str3.endsWith('.html'));
console.log(str3.endsWith('.htm'));
console.log(str3.endsWith('.php'));
console.log(str3.endsWith('.jpg'));

6.数值扩展

​ Number.isFinite : 判断是否是有限大

​ Number.MAX_VALUE : 数字最大值

​ Number.isInteger : 判断是否是整数

​ Number.parseInt : 将字符串转换为整型

​ Math.trunc : 向下取整

// Number.isFinite  :  判断是否是有限大
// 判断数字是否有限大  在JS中  我们数字是有上限的  也就是说  我们数字中有最大值
// 超过这个最大值  JS就不再支持
console.log(Number.isFinite(1.7976931348623157e+308));
console.log(Number.isFinite(1.7976931348623157e+309));
console.log(Number.isFinite(Infinity));
console.log(9999**99);
console.log(Number.isFinite(9999**99));
console.log('*'.repeat(60));


// Number.MAX_VALUE  : 取出JS中数字最大值
console.log(Number.MAX_VALUE);
console.log(1.7976931348623157e+308);
console.log(1.7976931348623157e+309);  // Infinity
console.log('*'.repeat(60));


// Number.isInteger  :  判断是否是整数
console.log(Number.isInteger(3));
console.log(Number.isInteger(3.));
console.log(Number.isInteger(3.0));
console.log(Number.isInteger('3'));
console.log(Number.isInteger(3.0000000000000001));
console.log(3.0000000000000005);
console.log('*'.repeat(60));

// Number.parseInt  :   将字符串转换为整型
console.log(Number.parseInt('12a3'));
console.log(Number.parseInt('1.2a3'));
console.log(Number.parseInt('a1.2a3'));
console.log(Number.parseInt('1.23'));
console.log('*'.repeat(60));

// Math.trunc  :  向下取整
console.log(Math.trunc(2.2));
console.log(Math.trunc(2.1));
console.log(Math.trunc(2.4));
console.log(Math.trunc(2.5));
console.log(Math.trunc(2.9));
console.log(Math.trunc(2.9999999999999999));

7.对象扩展

​ Object.is : 判断v1,v2数据是否完全相等

​ Object.assign : 将源对象source的属性复制到新的目标target对象上

​ Object.keys : 取出对象的键 返回一个数组

​ Object.values : 取出对象的值 返回一个数组

// Object.is  判断两个对象是否相等
let obj1 = {name:'Eric',age:18};
let obj2 = {name:'Eric',age:18};
// console.log(obj1 == obj2);
// 使用is方法进行判定  内置两个参数  参数是两个对象  进行比较
console.log(Object.is(obj1,obj2));
let str1 = 'qwe';
let str2 = 'qwe';
console.log(Object.is(str1,str2));


// assign方法  将一个对象中的属性   分配给另一个对象
let obj3 = {name:'Eric',age:18,sex:'男'};
let obj4 = {username :'admin',password : '123'};
let newObj = {};
// 使用assign方法  内置参数若干
// 第一个参数是接受属性的对象  后面的参数都是赋予属性的对象
// Object.assign(newObj,obj3);
// console.log(newObj);
Object.assign(newObj,obj3,obj4);
console.log(newObj);


// Object.keys  :  取出对象中所有的键  返回一个数组
// Object.values  :  取出对象中所有的值  返回一个数组
let obj = {name:'Eric',age:18,sex:'男'};
console.log(Object.keys(obj));
console.log(Object.values(obj));

​ Object.create : 以一个对象为原型创建另一个对象

let obj = {name:'Eric',age:18,sex:'男'};
/*
    create  :  以一个对象为原型  创建另一个对象
    实质上他只是实现了一个对象的继承
    内置两个参数  第一个参数是原型对象
    第二个参数是一个描述  描述就是一个对象
        对象中的键就是我们新建对象的属性
        对象中的值还是一个对象
            这个对象中有4个属性  这四个属性就是对属性的修饰
            value  :  属性的值
            writable : 修饰属性是否可写   是不是可以修改  默认是false
            configurable  : 修饰属性是否可删除   默认为false
            enumerable  :  修饰属性是否课遍历  默认为false
    返回值是创建的对象
*/
let newObj = Object.create(obj,{
    school : {
        value : '吉林大学',
        writable : false,
        configurable : false,
        enumerable : false
    },
    address : {
        value : '吉林长春',
        writable : true,
        configurable : true,
        enumerable : true
    }
})

console.log(newObj);
// console.log(newObj.name);
// 修改属性
newObj.address = "河北廊坊";
newObj.school = "慕尼黑大学";
console.log(newObj);

// 删除属性
// delete newObj.address;
// delete newObj.school;
// console.log(newObj);

// 遍历对象
for (let key in newObj){
    console.log(newObj[key]);
}

​ Object.defineProperties : 给对象添加属性

// 创建一个原型对象
let obj = {firstName : "良辰",lastName : "叶"}

// 使用defineProperty方法添加一个对象属性
// 内置三个参数  第一个参数是原型对象   第二个参数是对象的键
// 第三个参数是描述   描述是一个对象   对象的键是value  对象的值是添加的属性值
// Object.defineProperty(obj,'fillName',{
//     value : '叶良辰'
// })

// console.log(obj);




/*
    使用defineProperties方法添加对象属性  这次可以添加多个
    内置两个参数  第一个参数是原型对象
    第二个参数是一个描述  描述是一个对象
        对象中的键   使我们要添加的属性的名字
        对象中的值是一个描述  这个描述中的属性包括create方法中的属性
            对象中可以内置两个方法
                get方法  :  获取新增属性的时候会被自动调用
                set方法  :  修改新增属性的时候  会被自动调用

*/
Object.defineProperties(obj,{
    fillName : {
        // value : '叶良辰',
        get(){
            return this.lastName + this.firstName;
        },
        set(rename){
            // console.log('你呀改我干啥  还把我改成' + rename);
            this.lastName = rename.slice(0,1);
            this.firstName = rename.slice(1);
        }
    }
})
console.log(obj.fillName);
obj.fillName = '赵日天';
console.log(obj.fillName);
console.log(obj);
obj.fillName = "上官海棠";
console.log(obj);






let object = {
    username : '张飞',
    get username(){
        // console.log('我改名了   我叫关羽');
        return '我改名了   我叫关羽'
    },
    set username(x){
        console.log('修改了username  修改的是' + x);
    }
}
console.log(object.username);
// object.username = 123;
console.log(object);

8.数组扩展

​ Array.from : 将伪数组对象或者可遍历的对象 转换成真数组

​ Array.of : 将一系列的值转换为数组

​ find : 找出第一个满足条件的元素

​ findIndex : 找出第一个满足条件元素的索引

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <button>按钮1</button>
    <button>按钮2</button>
    <button>按钮3</button>
    <button>按钮4</button>
    <button>按钮5</button>
    <button>按钮6</button>
    <button>按钮7</button>
    <button>按钮8</button>
</body>
</html>
<script>
// 数组的扩展
// Array.from  :  将伪数组对象或者可遍历的对象 转换成真数组
let oBtns = document.getElementsByTagName('button');
console.log(oBtns);
console.log(Object.prototype.toString.call(oBtns));
let arr = Array.from(oBtns);
console.log(Object.prototype.toString.call(arr));
arr.forEach(element => {
    console.log(element);
});


// Array.of  :  将一系列的值转换为数组
// 其实就是一个创建数组的方式  内置参数若干 会将每一个参数  都转换成数组元素
let data = Array.of(1,7,3,0,1,0,7,9,2,0,1);
console.log(data);
console.log(Object.prototype.toString.call(data));


// find  :  找出第一个满足条件的元素
// 和filter类似  filter是返回数组中所有符合条件的元素  返回值是一个数组  即使没有满足条件的元素  那么也会返回一个空数组
// 但是find只是查找第一个满足条件的元素  返回值是一个数组元素  如果说没有满足条件的元素  那么返回undefined
// 传参方式和filter保持一致
// let res = data.filter(element=>element%2==0);
// let res = data.filter(element=>element%2==13);
// console.log(res);
// let result = data.find(element=>element%3==0);
let result = data.find(element=>element%3==13);
console.log(result);


// findIndex  :  找出第一个满足条件元素的索引
// 传参方式和find保持一致
// 如果说找不到满足条件的下标  返回值是-1
// let index = data.findIndex(element=>element%3==0);
let index = data.findIndex(element=>element%13==26);
console.log(index);
</script>

9.深度克隆

​ 深度克隆其实就是我们所说的深拷贝

1.浅拷贝

​ 拷贝对象其实就是复制对象 而浅拷贝指的是 拷贝之后 当一个对象发生改变的时候 另一个对象 也会跟着改变

​ 浅拷贝只是拷贝了对象的栈空间的地址 没有拷贝堆空间的内存

// 直接拷贝
// let arr = [66,88,99];
// let newArr = arr;
// console.log(arr);
// console.log(newArr);
// arr.push(33)
// newArr.push(44);
// console.log(arr);
// console.log(newArr);


// 使用...进行浅拷贝
// let arr = [66,88,99,[11,22,33]];
// let newArr = [...arr];
// console.log(arr);
// console.log(newArr);
// arr[3].push(999);
// console.log(arr);
// console.log(newArr);


// 使用assign也是浅拷贝
// let obj = {
//     name : 'Eric',
//     age : 18,
//     arr : [11,22]
// };
// let newObj = {}
// Object.assign(newObj,obj);
// console.log(obj);
// console.log(newObj);
// obj.arr[2] = 12356464;
// console.log(obj);
// console.log(newObj);



// 使用JSON.parse都是浅拷贝
let obj = {
    name : 'Eric',
    age : 18,
    say : ()=>{
        console.log(123);
    },
    arr : [11,22]
};
let newObj = JSON.parse(JSON.stringify(obj));
console.log(obj);
console.log(newObj);

2.深拷贝

​ 深拷贝指的是 拷贝之后 一个对象发生改变 不会影响另一个对象

​ 深拷贝不仅仅拷贝了栈空间的地址 也拷贝了堆空间的内存

// let obj = {name : 'Eric',age : 18,sex : '男'};
let obj = {name : 'Eric',age : 18,sex : '男',gk:[146,157,286]};

// let arr = [11,33,55,77,99];
let arr = [11,33,55,77,99,[22,44,66,88]];


// 定义一个函数  完成深度克隆
function deepCopy(object){
    let result = null;
    if (Object.prototype.toString.call(object) == '[object Array]'){
        result = [];
    }else if (Object.prototype.toString.call(object) == '[object Object]'){
        result = {};
    }else{
        return object;
    }
    // 遍历对象或者是数组  进行处理  使用for...in
    for (let key in object){
        if (typeof object[key] == 'object'){
            result[key] = deepCopy(object[key])
        }else{
            result[key] = object[key];
        }
        
    }
    return result
}

let newArr = deepCopy(arr);   // [object Array]
let newObj = deepCopy(obj);   // [object Object]
// console.log(newArr);
// console.log(newObj);

// 测试对象  和对象中的数组
newObj.gk.push(35);
console.log(obj);
console.log(newObj);

// 测试数组  数组中的数组
newArr[5].push(1234567890);
console.log(arr);
console.log(newArr);
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值