JS__精简__(2/2)

代码-函数前的各种符号


/* 常见的函数调用 */
(function () { })(); // 没有返回值的函数默认返回undefined

/* 【!】 对返回值的真假取反 */
console.log(!function () { return }());    // true,undefined属于false
console.log(!function () { return 0 }());  // true(取反操作)
console.log(!function () { return 1 }());  // false(取反操作)

/* 【+ -】 对返回值进行数学运算 */
console.log(+function () { return 5.1 }());  // 5.1
console.log(-function () { return 5.1 }());  // -5.1

/* 【~】 对返回值按位取反 */
//  所有正整数的按位取反是本身 +1 的负数,   所有负整数的按位取反是本身 +1 的绝对值,0 的按位取反是 -1
console.log(~function () { return 5 }());   // -6
console.log(~function () { return -5 }());  // 4
console.log(~function () { return 0 }());   // -1

代码-各种运算符

// 【双问号运算符】 
/*
  作用是当一个表达式是 null 或者 undefined 时为变量设置一个默认值
  这个运算符只会在左侧表达式是 null 或 undefined 时返回右侧的表达式
  空值合并运算符会允许把 0 和空字符串作为有效的数值。
*/
let bx = { name: 'abc' };
// bx.name ??='123';  // 存在将不赋值覆盖 不存在则创建

// 【三元运算符】 
var isNull = null; console.log(isNull ?? 'content');
n > 1 ? true : false // 单个判断
n > 1 ? 'Big' : n < 1 ? 'Small' : false; // 多个判断

/* 或运算符,与运算符 */
function inputCheck(e) {
    const val = e.key || "Not Found KeyName";
    console.log(val);
}
var obj = { k: "这是一个键值" };
inputCheck(obj);
// 【||】
/*
  1.没写||的情况:不存在的键名,默认返回undefined 
  2.写||情况: 不存在的键名,会执行后面语句 (类似于??)
  【例子】
  false / 0  || "value"  >>> "value"
  true  / 1  || "value"  >>> true
  undefined / null / NaN || "check" >>> "check"
  Infinity || else >>> Infinity 
  const value=e.key;           // bad  solution
  const value = e.key || '';   // good solution
*/
// 【&&】
/*
  true  / 1 && "code"  >>> "code" (if简写方法)
  false / 0 && "value" >>> false
  Infinity && "code" >>> "code"
  if(condition){expression}    // Bad  Solution
  codition && expression       // Good Solution
*/

代码-defer/async区别

/* defer与async区别: */
/*
 defer:
       当前页面解析完成之后才执行js代码
       特别是比较大的脚本,提高整个网页的载入速度是非常明显
 async:
       在当前js文件加载完成后,执行js代码
*/

/* 方法1 */
// 这种加载方式执行完之前会阻止onload事件的触发
(function () {
  var scriptEle = document.createElement("script");
  scriptEle.type = "text/javasctipt";
  scriptEle.async = true;
  scriptEle.src = "http://cdn.bootcss.com/jquery/3.0.0-beta1/jquery.min.js";
  var x = document.getElementsByTagName("head")[0];
  x.insertBefore(scriptEle, x.firstChild);
})();

/* 方法2:onload异步加载 */
// 这种方法只是把插入script的方法放在一个函数里面
// 然后放在window的onload方法里面执行,这样就解决了阻塞onload事件触发的问题。
(function () {
  if (window.attachEvent) {
    window.attachEvent("load", asyncLoad);
  } else {
    window.addEventListener("load", asyncLoad);
  }
  var asyncLoad = function () {
    var ga = document.createElement("script");
    ga.type = "text/javascript";
    ga.async = true;
    ga.src =
      ("https:" == document.location.protocol ? "https://ssl" : "http://www") +
      ".google-analytics.com/ga.js";
    var s = document.getElementsByTagName("script")[0];
    s.parentNode.insertBefore(ga, s);
  };
  // asyncLoad ();
})();

/* 方法3:Promise异步加载 */
// Promise提供了一种更合理、更强大的异步解决方案
var success = false;
const p = new Promise(function (resolve, reject) {
  if (success) {
    resolve("成功的结果");
  } else {
    reject("失败的结果");
  }
});
p.then(
  function (res) {
    console.log("接收resolve传来的数据....");
  },
  function (err) {
    console.log("接收reject传来的数据....");
  }
);
p.catch(function (err) {
  console.log("接收reject传来的数据或者捕获到then()中的运行报错时");
});
p.finally(function () {
  console.log(">>>>>>>>>>>");
});

/* 方法4:自定义异步加载 */
// (封装一个函数兼容性的异步加载js文件并且可以按需执行该文件里面的函数(按需加载))
function loadScript(url, callback) {
  var script = document.createElement("script");
  if (script.readyState) {
    script.onreadystatechange = function () {
      if (script.readyState == "complete" || script.readyState == "loaded") {
        callback();
      }
    };
  } else {
    script.onload = function () {
      callback();
    };
  }
  script.src = url;
  document.body.appendChild(script);
}
url = "http://cdn.bootcss.com/jquery/3.0.0-beta1/jquery.min.js";
function fc() {
  console.log("此函数运行状态...");
}
loadScript(url, fc);

代码-call/applly/bind区别

/* 参数 */
/*
    call(object,参数);
    apply(object,[数组参数]);
    bind(objet,参数)();
*/

/* 例子1 */
var c = { v: '测试内容' };
function callBack(s) { console.log(this.v + ' ' + s); };
callBack.call(c, 'call:content');
callBack.apply(c, ['apply:content']);
callBack.bind(c, 'bind:content')();

/* 例子2(进阶) */
var he = { name: '德玛', code: 4 };
var me = {
    name: '剑圣', code: 10,
    myFun: function (from, city) {
        console.log(
            this.name + ' 编号:' +
            this.code, '来自:' +
            from + ' 去往:' +
        city
        );
    }
};
me.myFun.call(he, '联盟', '水晶');
me.myFun.call(me, '联盟', '水晶');

/* 例子3(bind进阶) */
function mj(n2, n3) { return console.log(this.x, n2, n3); };
var m = mj.bind({ x: 10 }, 20);
m(30);

代码-null/undefined/Infinity/NaN

/* null */
/*
    无值|初始化变量
    null表示'没有对象',即该处不应该有值。
    用来初始化一个变量,这个变量可能被赋值为一个对象。
    当函数的参数期望是对象时,被用作参数传入。
    函数的返回值期望是对象时,被用作返回值传出
    【区别】 Undefined 与 null 的值相等,但类型不相等 
*/

/* undefined */
/*
    未声明|未赋值
    undefined表示'缺少值',就是此处应该有一个值,但是还没有定义。
    变量被声明了,但没有赋值时,就等于undefined。
    调用函数时,应该提供的参数没有提供,该参数等于undefined。
    对象没有赋值的属性,该属性的值为undefined。
    函数没有返回值时,默认返回undefined。
    【区别】 Undefined 与 null 的值相等,但类型不相等
*/

/* Infinity */
/*
    JavaScript 在计算数时超出最大可能数范围时返回的值
*/

/* NaN */
/* 
    属于JavaScript保留词,指示某个数不是合法数 
*/

代码-var/let/const区别 

/* var */
/*
  关键词声明的变量没有块作用域
  在块 {} 内声明的变量可以从块之外进行访问
  定义的全局变量属于 window 对象
  在相同的作用域,或在相同的块中,通过 var 重新声明一个 let 变量是不允许
  声明的变量会进行变量提升
  不存在关键性死区
  【共同】【var,let】函数作用域,全局作用域
*/

/* let */
/*
  关键词声明拥有块作用域的变量
  在块 {} 内声明的变量无法从块外访问
  定义的全局变量不属于 window 对象
  在相同的作用域,或在相同的块中,通过 let 重新声明一个 let 变量是不允许
  声明的变量不会进行变量提升
  存在关键性死区
  【共同】【var,let】函数作用域,全局作用域
*/

/* const */
/*
  与 let 变量类似,但不能重新赋值
  在块 {} 内声明的变量无法从块外访问
  无法重新声明声明或赋值
*/

代码-事件捕获与事件冒泡区别

/* 事件捕获与事件冒泡区别 */
{
    /* 基本了解 */
    /*
      阻止事件的冒泡方法 event.stopPropagation() 不让事件向document上蔓延
      阻止事件冒泡  // function fc(ev) { var en = ev || event; en.cancelBubble = true;};
      addEventListener(event,func,false); // 默认为false
      冒泡:false
      捕获:true
    例子: box 包含 item
    冒泡:里->向上延申(点击item,先触发item,后触发box)
    捕获:外->向下趋势(点击item,先触发box,后触发item)
    */
}

代码-鼠标坐标点细节

/* x,y/clientX,clientY/pagex,pageY/offsetX,offsetY/screenX,screenY区别: */

/*
    鼠标坐标点 x,y
    鼠标坐标点(__不随滚动条改变而改变__) clientX,clientY
    鼠标坐标点(__随滚动条滚动而改变__) pageX,pageY
    鼠标坐标点(__相对于目标元素边缘位置__) offsetX,offsetY
    鼠标坐标点(__相对于显示器(手机/电脑/其它)屏幕__) screenX,screenY
*/

代码-元素的尺寸细节

/* screen.width/offsetWidth/clientWidth/innerWidth/outerWidth区别: */

/*
  clientWidth  返回该元素的像素宽度,宽度包含padding,不包含border,margin和滚动条,是一个整数,单位是像素 px。
  offsetWidth  返回该元素的像素宽度,宽度包含padding,border,不包含margin,是一个整数,单位是像素 px。
  innerWidth   返回窗口的文档显示区的宽度,如果有水平滚动条,也包括滚动条高度。
  outerWidth   属性设置或返回窗口的外部宽度,包括所有的界面元素(如工具栏/滚动)。
  screen.width 属性声明了显示浏览器的屏幕的宽度
*/

代码-遍历细节

/* map与forEach */
/*
  1.map速度比forEach快
  2.map会返回一个新数组,不对原数组产生影响,foreach不会产生新数组,forEach返回undefined
  3.map因为返回数组所以可以链式操作,forEach不能
  4.map里可以用return
*/
/* 参数列表 */
/*
  every: 是否全部通过测试
  some: 其中一个是否通过测试
  filter: 返回新数组,通过测试的有哪些
  map: 返回新数组-所有元素进行修改(返回true|false)
  forEach: 按顺序为数组中的每个元素调用一次函数
  reduce: 函数的返回值存储在累加器中(结果/总计),通常应用统计(加减乘除)的总和
*/


// every 是否全部通过测试(&&)
var numbers = [45, 24, 29, 26, 25];
var p_every = numbers.every(f_every);
function f_every(value, index, array) {
    return value > 18;
}
console.log(p_every); // >>> true

// some  其中一个是否通过测试 (||)
var numbers = [45, 4, 9, 16, 25];
var p_some = numbers.some(f_some);
function f_some(value, index, array) {
    return value > 18;
}
console.log(p_some); // >>>true

// filter 返回新数组-通过测试的有哪些
var numbers = [45, 4, 9, 16, 25];
var p_filter = numbers.filter(f_filter);
function f_filter(value, index, array) {
    return value > 18;
}
console.log(p_filter); // >>> [ 45, 25 ]

// map 返回新数组-所有元素进行修改 / 进行大小判断-返回true|false
var numbers = [45, 4, 9, 16, 25];
var p_map = numbers.map(f_map);
function f_map(value, index, array) {
    return value * 2;
}
console.log(p_map); // >>> [ 90, 8, 18, 32, 50 ]

// forEach 按顺序为数组中的每个元素调用一次函数
var txt = "";
var numbers = [45, 4, 9, 16, 25];
numbers.forEach(f_foreach)
function f_foreach(value, index, array) {
    return txt = txt + value + "-";
}
console.log(txt) // >>> 45-4-9-16-25- 


// reduce 将数组的值减为单个值(从左到右) / 函数的返回值存储在累加器中(结果/总计)
var numbers = [15.5, 2.3, 1.1, 4.7];
var p_reduce = numbers.reduce(getSum);
function getSum(total, num) {
    return total + num;
}
console.log(p_reduce); // >>> 23.6


/* 区别 */
let box = [1, 2, 3, 4, 5];
console.log(box.map((item) => 2 * item));     // >>> [ 2, 4, 6, 8, 10 ]
console.log(box.filter((item) => item > 2));  // >>> [ 3, 4, 5 ]
console.log(box.find((item) => item > 2));    // >>> 3
console.log(box.every((item) => item < 5));   // >>> false
console.log(box.findIndex((item) => item === 3)); // >>> 2
console.log(Array.from(box, (item) => item * item)) // >>> [ 1, 4, 9, 16, 25 ]

代码-(==)/(===)区别

/* 
   ===  类型和值同时相等
   ==   值相等
*/

代码-String/toString区别

/* 区别 */
/*
  toString 对 undefined,null 转换出错
  String 相对 toString 更全面
*/
// 例子
(undefined).toString() // TypeError
(null).toString()      // TypeError

代码-变量赋值/对象赋值区别

// 变量赋值
var b1 = 1, b2 = b1;
b2 = 2;
console.log(b1, b2);
// >>> 1 2

// 对象赋值
var r1 = { a: 1 }, r2 = r1;
r2.a = 2
console.log(r1.a, r2.a)
 // >>> 2 2

代码-this细节

// 例子
let obj = {
    a: function () {
        // this指向obj
        console.log(this);
    },
    b: () => {
        // this指向window
        console.log(this);
    }
}
obj.a();
obj.b();

代码-防抖/节流区别

/* 区别 */
/*
  同样延迟1秒后触发情况
  防抖-1秒内无论如何快速点击,只有松开后才会触发,否则就不断重新开始计数为止
  节流-无论如何快速点击,1秒就1次发生
  应用:防抖-用户输入,节流-跳转页面
*/

/* 防抖 */
var fd = document.getElementById('fangdou');
var fdt = document.querySelector('#fangdou+p');
function fang_dou(fn, wait) {
    let timeout = null;
    return function () {
        // 每一次点击判断有延迟执行的任务就停止
        if (timeout != null) { clearTimeout(timeout); };
        // 否则就开启延迟任务
        fdt.innerHTML = '....';
        timeout = setTimeout(fn, wait);
    };
};
function fdtest() { fdt.innerHTML = '防抖成功'; };
fd.addEventListener('click', fang_dou(fdtest, 1000));

/* 节流 */
var jl = document.getElementById('jieliu');
var jlt = document.querySelector('#jieliu+p');
function jie_liu(fn, wait) {
    let bool = true;
    return function () {
        if (!bool) { return };
        bool = false;
        setTimeout(() => {
            //fn() fn中this指向window
            fn.call(this, arguments);
            bool = true;
        }, wait);
    };
};
function jltest() { jlt.innerHTML = '节流成功....'; };
jl.addEventListener('click', jie_liu(jltest, 1000));

代码-懒加载

// 懒加载-延迟加载,按需加载
var imgs = document.querySelectorAll('.box');
function lozyLoad() {
    var scrollTop = document.body.scrollTop || document.documentElement.scrollTop;
    console.log('top:', scrollTop);
    var winHeight = window.innerHeight;
    console.log('win:', winHeight)
    for (let i = 0; i < imgs.length; i++) {
        console.log(imgs[i].offsetTop, scrollTop, winHeight)
        if (imgs[i].offsetTop < scrollTop + winHeight) {
            //设置延迟 预留缓冲->效果对比
            setTimeout(() => {
                imgs[i].style.background = imgs[i].getAttribute('data-bg');
            }, 1000)
            //CSS-过渡效果
            /*
            imgs[i].style.transition='2s'
            imgs[i].style.background=imgs[i].getAttribute('data-bg');
            */
        }
    }
};
window.onscroll = function () { lozyLoad() };

代码-promise 

/* promise异步 */

/* 基本了解 */
/*
  相当于一个容器,保存着未来才会结束的事件(异步操作)的一个结果
  【特点】
  1.对象的状态不受外界影响
  2.处理异步的操作 三个状态: Pending 进行中/ Resolved 成功/  Rejected 失败
*/
/* 参数列表 */
/*
  all     用于异步并行操作
  race    用于请求超时操作
  resolve 返回异步操作成功的结果
  reject  回异步操作失败的结果
  then    执行Promise状态是成功的操作(异步执行)
  catch   执行Promise状态是失败的操作(异步执行)
  finally 成功或失败都执行操作
  done    始终执行
*/

// 例子1
let pro1 = new Promise(function (resolved, rejected) { });
console.log(pro1);

// 例子2:简单异步操作
let pro2 = new Promise(function (resolved, rejected) {
    // 执行异步操作
    let res = { code: 201, data: { name: '小马哥' }, err: '失败' };
    setTimeout(() => {
        if (res.code === 200) {
            resolved(res.data);
        } else {
            rejected(res.err);
        };
    }, 1000);
});
console.log(pro2);
pro2.then((success) => { console.log(success); }, (err) => { console.log(err); });

// 例子3:异步并行操作(复杂)
let p1 = new Promise((resolve, reject) => { });
let p2 = new Promise((resolve, reject) => { });
let p3 = new Promise((resolve, reject) => { });
let p4 = Promise.all([p1, p2, p3])
p4.then(() => {
    // 三个都成功 才成功
}).catch((err) => {
    // 如果有一个失败 则失败
});

// 例子4:请求超时操作
// 请求图片资源
function requestImg(imgSrc) {
    return new Promise((resolve, reject) => {
        const img = new Image();
        img.onload = function () {
            resolve(img);
        };
        img.src = imgSrc;
    });
}
function timeout() {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            reject(new Error("图片请求超时"));
        }, 3000);
    });
}

// 参数:数组
Promise.race([requestImg("https://img1.baidu.com/it/u=1310564963,1641173348&fm=253&fmt=auto&app=120&f=JPEG?w=1280&h=800"), timeout()])
    .then((res) => {
        // 3秒内请求成功 执行then方法
        console.log(res);
        document.body.appendChild(res);
    })
    .catch((err) => {
        // 超过3秒 执行catch方法
        console.log(err);
    });

代码-async

/* async */

/* 作用 */
/*
   使得异步操作更加方便
   基本操作:async它会返回一个Promise对象 then catch
   async是Generator的一个语法糖 
*/
async function f() {
    let s = await 'hello world'
    let data = await s.split('')
    return data;
}
f().then(v => console.log(v)).catch(e => console.log(e));
async function f2() { throw new Error('出错了'); };
f2().then(v => console.log(v)).catch(e => console.log(e));

代码-构造函数

/* 构造函数 */

// 数组
Array.prototype.len = function () { console.log(this.length) };
var arr = ['a', 'b', 'c'];
arr.len();

// 对象
Object.prototype.sum = function () { let sum = this.a + this.b + this.c; console.log(sum); };
var obj = { a: 1, b: 2, c: 3 };
obj.sum();

// 字符串
String.prototype.len = function () { console.log(this.length); };
var str = '123456789';
str.len();

代码-argument

// 例子1:函数参数查看
function fc() {
    var x = 10, y = 20;
    console.log(arguments[1]);
};
fc('abc', '123'); // >>> 123

// 例子2:阶乘的实现
var factorial = function (n) {
    /**
     * @注释 n === 1 必须返回1 否则n将无限迭代
     * @function callee 返回正在被执行的函数对象,只能在相关的函数 执行时才能使用
     * @应用 实行函数的递归
     */
    return 1 === n ? 1 : n + arguments.callee(n - 1);
};
console.log(factorial(5)); // >>> 120

 代码-Generator/Interator

/* Generator生成器/Interator迭代器 */
/*
  生成器:
  yield是JS为了解决异步调用的命令
  表示程序执行到某个阶段会交出执行权,等待结果返回
  需要在协程Generator函数中运行,函数名之前要加星号,以示区别
  调用Generator函数,返回一个内部指针(遍历器g,执行不会返回结果,返回的是指针对象)
  调用指针g的next方法,移动内部指针(执行异步任务的第一段)指向第一个遇到的yield语句 
  生成器不会立即执行,需要调用next()才会执行,调用return()则会终止生成器的运行
*/

/* generator */
// 例子1
function* gen(x) {
    var y = yield x + 2;
    return y;
};
var g = gen(1);
var n1 = g.next(); var n2 = g.next();
console.log(n1); console.log(n2);

// 例子2-快捷方法
function* foo() {
    /* 方法1  yield 1; yield 2; yield 3; */
    yield* [1, 2, 3];
};
var f = foo();
console.log(f.next().value);
console.log(f.next().value);
console.log(f.next().value);

// 例子3
function* add() {
    console.log('start');
    let x = yield '2'
    console.log('one:' + x)
    let y = yield '3'
    console.log('two:' + y)
    return x + y;
}
const fn = add();
console.log(fn.next());
console.log(fn.next(20));

/* interator */
const arr = ['one', 'two', 'three'];
// 创建新的迭代器
const item = arr[Symbol.iterator]();
console.log(item.next()); // one
console.log(item.next()); // two

代码-闭包

/* 基本了解 */
/*
   函数和函数内部能访问到的变量的总和,就是一个闭包
*/
var local = '变量';
function foo() { 
    console.log(local) 
};

代码-解构/展开/交换

/* 对象解构 */
// const { name, id } = obj

/* 数组展开 */
// ...arr

/* 变量交换 */
//  [a, b] = [b, a]

代码-深拷贝/浅拷贝

/* 浅拷贝 */
/*
   浅拷贝-只复制对象的第一层属性,深拷贝可以对对象的属性进行递归复制
   浅拷贝只是拷贝了内存地址
   浅拷贝增加了一个指针指向已存在的内存
   子类的属性指向的是父类属性的内存地址
   当子类属性修改后,父类属性也随之修改
*/
var a = { name: 'Jerry', age: 20 };
var b = a;
b.name = 'Tom';   
console.log(a, b); // >>> { name: 'Tom', age: 20 } { name: 'Tom', age: 20 }


/* 深拷贝 */
/*
  深拷贝可以对对象的属性进行递归复制,浅拷贝-只复制对象的第一层属性
  深拷贝就是增加一个指针,并申请一个新的内存
  并且让这个新增的指针指向这个新的内存地址使用深拷贝
  当复制原对象但不能修改原对象的时候,就得使用深拷贝
*/
var c = { name: 'abc', n: '123' };
var d = JSON.parse(JSON.stringify(c));
d.name = 'def';   
console.log(c, d); // >>> { name: 'abc', n: '123' } { name: 'def', n: '123' }

var text = ['123', '456', '789']
var new1 = JSON.parse(JSON.stringify(text))
new1[0] = '000'
console.log(new1) // >>> [ '000', '456', '789' ]

 代码-ES6模块导出导入

/* 参数列表 */
/*
    export 用于规定模块的对外接口
    import 用户输入其它模块提供的功能
*/

// 例子1-基本配置
/*
    Nodejs 安装 anywhere
    终端:anywhere 自动配置localhost:port*
    index.html(默认为主页)
*/

/* 方法1:常规导入 */
/*
    // index.js 
    代码:
        export const name = '张三'
        export const age = 18
        export function sayName(){ return 'my name' }

    // index.html
    代码:
        <script type='module>
            import {name,age,sayName} from './modules/index.js'
            console.log(name,age,sayName())
        </script>
*/

/* 方法2:展开导入 */
/*
    // index.js
    代码:
        const name = '张三'
        const age = 18
        const function sayName(){ return 'my name'}
        export{ name,age,sayName }
        const obj={ foo:'foo'}
        export default obj;

    // index.html
    代码:
        import obj,{name,age,sayName} from './modules/index.js'
        console.log(obj,name)
*/

/* 自定义命名 */
/*
    import * as f from './modules/index.js'
    console.log(f); console.log(f.default);
*/

代码-原型链

/* 参数列表 */
/*
  constructor     对创建对象的函数的引用(指针),对于 Object 对象,该指针指向原始的 Object() 函数
  Prototype       对该对象的对象原型的引用,对于所有的对象,它默认返回 Object 对象的一个实例。
  hasOwnProperty  判断对象是否有某个特定的属性。必须用字符串指定该属性。
  IsPrototypeOf   断该对象是否为另一个对象的原型
  PropertyIsEnumerable    判断给定的属性是否可以用 for...in 语句进行枚举
  ToString  返回对象的原始字符串表示。对于 Object 对象
  ValueOf   返回最适合该对象的原始值。对于许多对象,该方法返回的值都与 ToString() 的返回值相同
*/
/* 原型链继承 */
function Parent() { this.a = 20 }
function Child() { this.b = 30 }
Child.prototype = new Parent()
let o2 = new Child()
console.log(o2, o2.name, o2.age)

代码-Solution

/* 假设-函数传递多个参数 */
{
    /* Bad Solution */
    // function fc(param1,param2,param3,param4,param5){...}
    /* Good Solution */
    // function fc({param1,param2,param3,param4,param5}){...}
    // 函数参数放入对象里
}

/* 假设-合并数组 */
{
    /* Bad Solution */
    var arr1, arr2;
    arr1 = arr1.concat(arr2)
    /* Good Solution */
    arr1 = [...arr1, ...arr2]
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

vip飞梦

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值