console
var a = [];
for (var i = 0; i < 10; i++) {
a[i] = function() {
console.log(i);
}
}
a[6]();
var b = [];
for (let j = 0; j < 10; j++) {
b[j] = function () {
console.log('test let', j);
}
}
b[6]();
if (true) {
var testLocalVar = 'hhahaahah';
}
console.log(testLocalVar);
function log(x, y) {
if (typeof y === 'undefined') {
y = 'world';
}
console.log('es5给参数y设置默认取值的方式', x, y);
}
log('hello');
log('hello', 'xiaokeai');
log('hello', '');
function logEs6(x, y = 'world') {
console.log('es6可以直接在参数定义的后面给参数设置默认值:', x, y);
}
logEs6('hello');
logEs6('hello', 'xiaokeai');
logEs6('hello', '');
function foo(x = 5) {
}
let defaultTestX = 99;
function testFuncDefaultParam(params = defaultTestX + 1) {
console.log('参数默认值不是传值的,是每次都重新计算默认值表达式的值', params);
}
testFuncDefaultParam();
defaultTestX = 600;
testFuncDefaultParam();
function testFuncCombine({param1, param2 = 5}) {
console.log("代码只使用了对象的解构赋值默认值,没有使用函数参数默认值,且若函数调用时没有提供参数,变量param1和param2不会生成,从而报错:", param1, param2);
}
testFuncCombine({});
testFuncCombine({param1: 1});
testFuncCombine({param1: 1, param2: 2});
function testFuncCombinePro({param1, param2 = 5} = {}) {
console.log("通过提供函数参数的默认值,可以避免这种情况:", param1, param2);
}
testFuncCombinePro();
function method1({x = 0, y = 0} = {}) {
console.log('函数默认值先生效', x, y);
}
function method2({x, y} = {x: 0, y: 0}) {
console.log('解构赋值的默认值后生效', x, y);
}
method1();
method2();
method1({x: 3, y: 9});
method2({x: 3, y: 9});
method1({x: 3});
method2({x: 3});
method1({});
method2({});
method1({z: 99});
method2({z: 99});
function funcParam(x = 1, y) {
console.log('参数1和参数2:', x, y);
}
funcParam();
funcParam(undefined, 1);
console.log('返回没有指定默认值的参数的个数:', (function(a) {}).length, (function (a = 5) {}).length);
console.log('设置默认值的参数不是尾参数,那从设置默认值到之后的参数都不计入length', (function (a = 0, b, c) {}).length);
console.log('同上', (function (a, b = 1, c) {}).length);
var testScopeX = 1;
function funcScope(testScopeX, paramY = testScopeX) {
console.log('参数paramY的默认值为testScopeX。调用该函数时,参数会形成一个单独作用域,在该作用域中,默认值变量testScopeX指向的是第一个参数,而非全局变量', paramY);
}
funcScope(4);
function funcScope1(paramY = testScopeX) {
let testScopeX = 3;
console.log('调用函数时,参数形成单独作用域,该作用域中变量testScopeX无定义,所以指向外层的全局变量testScopeX', paramY);
}
funcScope1();
console.log('全局变量testScopeX的值', testScopeX);
function funcScope2(paramY = testScopeX) {
var testScopeX = 66;
console.log('2.调用函数时,参数形成单独作用域,该作用域中变量testScopeX无定义,所以指向外层的全局变量testScopeX', paramY);
}
funcScope2();
console.log('全局变量testScopeX的值', testScopeX);
function funcScope3(testScopeX = testScopeX) {
console.log('调用会报错,参数实际执行的是let testScopeX = testScopeX,由于暂时性死区的原因,会报未定义的错误');
}
let funcBody = 'outer';
function funcScope4(func = () => funcBody) {
let funcBody = 'inner';
console.log('若参数是一个函数,那该函数的作用域也遵守该规则', func());
}
funcScope4();
function funcScope5(testScopeX, Y = function() {testScopeX = 2}) {
console.log('打印testScope:', testScopeX);
}
funcScope5();
console.log('全局变量testScopeX的值', testScopeX);
function funcScope6(testScopeX, Y = function() {testScopeX = 6}) {
Y();
console.log('funcScope6的testScopeX:', testScopeX);
}
funcScope6();
console.log('全局变量testScopeX的值', testScopeX);
function funcScope7(testScopeX, Y = function() {testScopeX = 7}) {
var testScopeX = 11;
console.log('funcScope7的testScopeX', testScopeX);
}
funcScope7();
console.log('全局变量testScopeX的值', testScopeX);
function funcScope8(testScopeX, Y = function() {testScopeX = 8}) {
var testScopeX = 16;
Y();
console.log('funcScope8的testScopeX', testScopeX);
}
funcScope8();
console.log('全局变量testScopeX的值', testScopeX);
function funcScope9(testScopeX, Y = function() {testScopeX = 9}) {
testScopeX = 18;
console.log('funcScope9的testScopeX', testScopeX);
}
funcScope9();
console.log('全局变量testScopeX的值', testScopeX);
function funcScope10(testScopeX, Y = function() {testScopeX = 10}) {
testScopeX = 20;
Y();
console.log('funcScope10的testScopeX', testScopeX);
}
funcScope10();
console.log('全局变量testScopeX的值', testScopeX);
function addAnyNum(...values) {
let sum = 0;
for(var val of values) {
sum += val;
}
return sum;
}
console.log('利用rest参数实现的对任意个数的参数进行求和:', addAnyNum(3, 4, 5, 6));
function sortNumbers() {
return Array.prototype.slice.call(arguments).sort();
}
const sortNumbersByRest = (...numbers) => numbers.sort();
function push(array, ...items) {
items.forEach(function(item) {
array.push(item);
console.log('给数组即第一个参数传入元素:', item);
});
}
var pushArrayByRest = [];
push(pushArrayByRest, 3, 4, 5, 6);
function add(x, y, z) {
let sum = x + y + z;
console.log ('三数之和' + sum);
}
const numbersArr = [3, 6, 9];
add(...numbersArr);
let x = 1;
let followExpression = [...(x && x > 0 ? ['a'] : []), 'b'];
console.log('扩展运算符后跟表达式的结果: ' + followExpression);
x = 0;
followExpression = [...(x && x > 0 ? ['a'] : [], 'b')];
console.log('扩展运算符后是空数组则不会有任何效果: ' + followExpression);
function testApply(x, y, z) {
console.log('利用Es5的apply方法实现将数组转为为函数的参数序列', x, y, z);
}
testApply.apply(null, ['param1', 'param2', 'param3']);
testApply(...['Es6Param1', 'Es6Param2', 'Es6param3']);
var arr1 = [0, 1, 2],
arr2 = [3, 4, 5],
arr3 = [6, 7, 8, 9];
Array.prototype.push.apply(arr1, arr2);
console.log('Es5将一个数组push到另一个数组尾部:', arr1);
arr1.push(...arr3);
console.log('Es6使用扩展运算符将arr3push到arr1中:', arr1);
var a1 = [1, 2],
a2 = a1,
a3,
a4;
a2[0] = 3;
console.log('Es5直接复制数组,复制的是引用', a1, a2);
a2 = a1.concat();
a2[0] = 4;
console.log('Es5可以利用concat来实现克隆一个新数组', a1, a2);
a3 = [...a2];
a3[0] = 5;
console.log('Es6可以直接使用扩展运算符实现克隆出一个新数组:', a2, a3);
[...a4] = a1;
a4[1] = 8;
console.log('Es6实现克隆出一个新数组的另一种写法:', a1, a4);
const array1 = ['arr1Elem1', 'arr1Elem2'];
const array2 = ['arr2Elem1', 'arr2Elem2'];
const array3 = ['arr3Elem1'];
var Es5NewArray = array1.concat(array2, array3);
console.log('Es5利用concat实现多个数组合并:',Es5NewArray);
console.log('Es6利用扩展运算符实现多个数组合并:', [...array1, ...array2, ...array3]);
var arrCopy = [{foo: 1}],
arrCopy2 = [{bar: 2}];
const arrCopy3 = arrCopy.concat(arrCopy2);
const arrCopy4 = [...arrCopy, ...arrCopy2];
console.log('Es5数组合并后都是浅拷贝: ', arrCopy3, arrCopy3[0] === arrCopy[0]);
console.log('Es6数组合并后也都是浅拷贝:', arrCopy4, arrCopy4[0] === arrCopy[0]);
var numList = [0, 1, 2, 3, 4];
var fstNum = numList[0],
restNums = numList.slice(1);
console.log('Es5利用slice来生成数组:', restNums);
var es6NumList = [6, 7, 8, 9, 10],
[es6FstNum, ...es6RestNums] = es6NumList;
console.log('Es6利用解构赋值和扩展运算符生成数组:第一个元素' + es6FstNum + ' ,剩余元素构成的数组' + es6RestNums);
const [first, ...rest] = [];
const [fstElem, ...restElems] = ["first"];
var strToArr = [...'hello\uD83D\uDE80y'];
console.log('扩展运算符将字符串转为真正数组,且能正确识别四个字节的Unicode字符:' + strToArr + '数组长度:' + strToArr.length);
function length(str) {
return [...str].length;
}
console.log('test four Byte Unicode length:', length('test\uD83D\uDE80'));
let domNodeList = document.querySelectorAll('div');
let domNodeArr = [...domNodeList];
console.log('扩展运算符可将实现了Iterator接口的NodeList对象转化为真正的数组: ', domNodeArr);
let mapToArr = new Map([
[1, 'one'],
[2, 'two'],
[3, 'three'],
]);
console.log('Map结构因为具有Iterator接口,可用扩展运算符转为数组:', [...mapToArr.keys()]);
let arrayLikeObj = {
'0': 'a',
'1': 'b',
'2': 'c',
length: 3
};
var es5arrLiketoArr = [].slice.call(arrayLikeObj);
console.log('Es5利用slice和call实现将类似数组转化为数组', es5arrLiketoArr);
let es6ArrLiketoArr = Array.from(arrayLikeObj);
console.log('Es6利用Array.from实现将类似数组对象转为数组', es6ArrLiketoArr);
let nodelist = document.querySelectorAll('div');
Array.from(nodelist).filter(divNode => {
return divNode.textContent.length > 6;
});
console.log('nodeList转换为数组并且过滤后,', nodelist);
function testArgumentsToArr(param1, param2) {
console.log('函数参数arguments', arguments);
console.log('使用Array.from转换为数组婚后', Array.from(arguments));
}
testArgumentsToArr('test1', 'test2');
let namesSet = new Set(['a', 'b']);
console.log('只要是部署了Iterator接口的数据结构,Array.from都能将其转换为数组', Array.from(namesSet));
console.log('若参数是一个真正的数组,Array.from会返回一个一模一样的新数组', Array.from([1, 2, 3]));
console.log('只要有length属性的对象,都可以用Array.from转换', Array.from({length: 3}));
console.log('Array.from的第二个参数类似于数组的map函数:', Array.from({'0': 1, '1': 2, '2': 3, length:3}, x => x * x));
console.log('等价于数组的map函数:', Array.from({'0': 1, '1': 2, '2': 3, length:3}, x => x * x));
console.log('Array构造函数无参时结果是一个空数组:', Array());
console.log('Array构造函数有一个参数时,表示几个元素:', Array(3));
console.log('Array构造函数多于一个参数时,参数就是具体的元素值:', Array(3, 9, 27));
console.log('Array.of方法的目的就是来解决Array函数由于参数不同而导致的重载问题,行为统一:', Array.of(3));
console.log('多于一个参数时:', Array.of(3, 7, 78));
console.log('即Array.of基本可以替代Array()或new Array(),并且具有统一行为:将一组数值转换为数组:', Array.of(), Array.of(undefined));
function ArrayOf() {
return [].slice.call(arguments );
}
console.log('使用数组实例的copyWithin方法复制某个位置的元素到指定位置:', [1, 2, 3, 4, 5].copyWithin(0, 3));
console.log('当start和end参数为负值时的情况:', [1, 2, 3, 4, 5].copyWithin(0, -2, -1))
console.log('类似数组对象,将3号位置复制到0号位:', [].copyWithin.call({length: 5, 3: 1}, 0, 3));
console.log('数组实例的find方法:找某个满足条件的成员', [1, 4, -5, 10].find((n) => n < 0));
let testArrayInstanceFind = [1, 5, 10, 15];
let arrInstanceFindRes = testArrayInstanceFind.find(function (value, index, arr) {
console.log('find方法的回调函数可以接受三个参数:当前值,当前位置,原数组:', value, index, arr);
return value > 9;
});
console.log('寻找的结果:', arrInstanceFindRes);
function testParam2(age) {
return age > this.age;
}
let personObj = {name: 'Jack', age: 20};
console.log('使用find的第二个参数来指定调用回调函数的this值:', [10, 18, 22, 20].find(testParam2, personObj));
console.log('findIndex的使用:', [1, 5, 10, 15].findIndex(function (value, index, arr) {
return value > 9;
}));
console.log('indexOf无法发现NaN:', [NaN].indexOf(NaN));
console.log('findeIndex可以发现NaN:', [NaN].findIndex(y => Object.is(NaN, y)));
console.log('利用fill方法可以对空数组做初始化操作', new Array(5).fill(7));
console.log('fill方法填充元素后,数组中已有的元素会被全部抹去:', ['a', 'b', 'c'].fill(8));
console.log('fill的第二个和第三个参数可分别指定填充的起始位置:', ['q', 'v', 'b', 'd'].fill(9, 1, 3));
let fillObjArr = new Array(3).fill({name: 'milke'});
fillObjArr[0].name = 'chao';
console.log('fill的填充值为对象时,填充的是同一个内存地址,不是对象的深拷贝:', fillObjArr[0].name, fillObjArr[1].name, fillObjArr[2].name);
let fillArrObjArr = new Array(4).fill([]);
fillArrObjArr[0].push(3);
console.log('fill的填充值为对象时,如数组,也是浅拷贝:', fillArrObjArr);
for (let [index, elem] of ['a', 'b', 'c'].entries()) {
console.log('利用entries遍历数组的键值对:', index, elem);
}
for(let index of ['elem1', 'elem2', 'elem3'].keys()) {
console.log('利用keys方法对数组的键名进行遍历:', index);
}
for(let value of ['elem1', 'elem2', 'elem3'].values()) {
console.log('利用values对数组的键值进行遍历:', value);
}
let testNextEntries = ['one', 'two', 'three'].entries();
console.log('手动调用next方法来完成对数组的遍历:', testNextEntries.next().value)
console.log('手动调用next方法来完成对数组的遍历', testNextEntries.next().value);
console.log('手动调用next方法来完成对数组的遍历', testNextEntries.next().value);
console.log('利用includes来判断数组是否包含指定值:', [1, 2, 3].includes(2));
console.log('includes也可以判断出NaN:', [2, 3, NaN, 4].includes(NaN));
console.log('includes可以指定搜索的起始位置:', [1, 2, 3].includes(3, 3));
console.log('Es5用indexOf来判断一方面语义化不强,还需要对返回值做判断,另一方面会对NaN做误判:', [NaN].indexOf(NaN));
let flatArr = [1, 2, [3, 4], [5, [6, 7]]];
console.log('flat将数组拉平且不影响原数组,默认拉平一层。原数组,拉平后:', flatArr.length, flatArr.flat(), flatArr.flat().length);
console.log('flat的参数可以指定拉平的层数:', flatArr.flat(2), flatArr.flat(2).length);
console.log('flat会跳过原数组的空位:', [1, 2, , 3, [5, 6]].flat().length);
let flatMapArr = [2, 3, 4].flatMap((x) => [x, x * 2]);
console.log('flatMap遍历数组执行回调函数,且对返回值执行flat:', flatMapArr, flatMapArr.length);
let flatMapArr1 = [2, 3, 4].flatMap((x) => [[x * 2]]);
console.log('flatMap默认只展开一层:', flatMapArr1, flatMapArr1.length, flatMapArr1[0].length);
let flatMapArr2 = [2, 3, 5].flatMap(function callback(current, index, arr) {
console.log('flatMap的回调函数的参数:', current, index, arr);
});
console.log('Array构造函数返回的数组都是空位:', Array(3));
console.log('Array总若数组成员取值是undefined,那也是有值的,不是空位!', [undefined, undefined, ,]);
console.log('in元素可以区分出一个位置是否有值:即undefined取值和空位:', 0 in [undefined, undefined], 0 in [, , ,]);
console.log('Es5中forEach方法会跳过空位:', [, 'a'].forEach((x, i) => console.log('第' + i + '个位置的元素是:' + x)));
console.log('Es5中filter方法会跳过空位:', ['a', , 'b'].filter(x => true));
console.log('Es5中every也会跳过空位:', [, 'a'].every(x => x === 'a'));
console.log('Es5中reduce方法会跳过空位处理:', [1, , 3].reduce((x, y) => x + y));
console.log('Es5中的some方法会跳过空位:', [, 'a'].some(x => x !== 'a'));
console.log('Es5中的map方法会跳过空位,但会保留该值:', [, 'a'].map(x => 1));
console.log('join方法会将空位视为undefined,进而转化为空字符串:', [, 'a', undefined, null].join('#'));
console.log('toString方法也会将空位视为undefined,进而转化为空字符串:', [, 'a', undefined, null].toString());
console.log('Es6中的Array.from方法将数组的空位转为undefined,不会忽略空位', Array.from(['a', , 'b']));
console.log('Es6中的扩展运算符也会将空位转为undefined', [...['a', , 'b']]);
console.log('Es6中的copyWithin会连空位一起拷贝:', [, 'a', 'b', ,].copyWithin(2, 0));
console.log('Es6中的fill会将空位视为正常的数组位置:', new Array(3).fill('a'));
let testEmptyPosArr = [, ,];
for (let i of testEmptyPosArr) {
console.log('for...of循环也会遍历空位:', i);
}
console.log('entries方法将空位处理成undefined:', [...[, 'a'].entries()]);
console.log('keys方法将空位处理成undefined:', [...[, 'a'].keys()]);
console.log('values方法将空位处理成undefined:', [, 'a'].values());
console.log('find方法将空位处理成undefined:', [, 'a'].find(x => true));
console.log('findIndex方法将空位处理成undefined:', [, 'a'].findIndex(x => true));
var set = new Set([1, 1, 2, 3, 4, 5, 5, 5]);
console.log('Set的实例的成员,没有重复值', set);
console.log('set的成员个数', set.size);
for(let item of set) {
console.log('set自身部署了iterator接口', item);
}
set.add(7);
set.delete(2);
if (set.has(3)) {
console.log('set含有成员3');
}
for(let key of set.keys()) {
console.log('使用keys方法遍历set的键名', key);
}
for(let value of set.values()) {
console.log('使用values方法遍历set的键值', value);
}
for(let [key, value] of set.entries()) {
console.log('使用entries遍历set的键值对', key, value);
}
set.forEach(function(item) {
return item * 2;
});
console.log('使用forEach对每个成员进行操作后的结果', set);
var ws = new WeakSet([[1, 2], [3, 4]]),
key = [7, 8];
ws.add([5, 6]);
console.log('ws', ws);
ws.add(key);
console.log('ws成员中有【7, 8】吗', ws.has(key));
var map = new Map([[true, 'ok'], [1, 2]]);
map.set([], '数组1');
map.set([], '数组2');
console.log('map的成员个数(键名不是同一个引用的对象,被视作不同键)', map.size);
for (let [key, value] of map) {
console.log('map的成员', key, value);
}
console.log('map的true成员的值:', map.get(true));
console.log('map是否具有1成员:', map.has(1));
for(let key of map.keys()) {
console.log('遍历map的key:', key);
}
for(let value of map.values()) {
console.log('遍历map的value:', value);
}
map.delete(1);
for(let [key, value] of map.entries()) {
console.log('遍历map的key:' + key + ' 和value:' + value);
}
console.log('用扩展运算符将Map转换为数组:', [...map]);
var arrToMap = new Map([
['key1', 1],
[{key: 2}, 2]
]);
for(let [key, value] of arrToMap) {
console.log('数组转化为map的key和value', key, value);
}
function stringMapToObj(stringMap) {
var obj = Object.create(null);
for(let [key, value] of stringMap) {
console.log('key,value:', key, value);
obj[key] = value;
}
return obj;
}
var strMap = new Map().set('yes', true).set('no', false);
console.log('键都为字符串的Map转为对象', stringMapToObj(strMap).yes, stringMapToObj(strMap).no);
<div class="parent">
<div class="child1">hhhhhh</div>
<div class="child2">lllllllll</div>
</div>