浅克隆
let copyObj = obj; // 赋值
let copyObj = Object.assign(obj); // 将源对象的属性赋值到目标对象上
let copyArr = arr.concat(); // 连接数组,不传参,则表示复制原数组
let copyArr = arr.slice(); // 截取数组或者字符串,不传参表示默认全部
深度克隆,避免引用值被更改
JSON.parse(JSON.stringify(data))
$.extend(true, [], data)
var obj = { name: 'Lee', age: 23, arr: [1, 2, 3], family: { name: 'home', son: { name: 'aaa', fun: function () { console.log(this.name); } } } } // var obj = [1,2,3] // var obj = null // var obj = undefined // var obj = NaN // var obj = /asdv/ function deepClone(origin) { var target, toStr = Object.prototype.toString; if(toStr.call(origin) === '[object Object]'){ target = { }; for (var key in origin) { if (origin.hasOwnProperty(key)) { target[key] = arguments.callee(origin[key]) } } }else if(toStr.call(origin) === '[object Array]'){ target = []; for (var key in origin) { if (origin.hasOwnProperty(key)) { target[key] = arguments.callee(origin[key]) } } }else{ target = origin; } return target; // ===> 简写 // var toStr = Object.prototype.toString; // var target = toStr.call(origin) === '[object Object]' ? {} : (toStr.call(origin) === '[object Array]' ? [] : origin); // if(toStr.call(origin) === '[object Object]' || toStr.call(origin) === '[object Array]'){ // for (var key in origin) { // if (origin.hasOwnProperty(key)) { // target[key] = arguments.callee(origin[key]) // } // } // } // return target; } var copyObj = deepClone(obj); console.log(copyObj); obj.arr.push(2) copyObj.arr.push(3) console.log(obj.arr, copyObj.arr); obj.family.son.name = 'NAM' copyObj.family.son.name = 123 console.log(obj.family.son.name, copyObj.family.son.name); copyObj.family.son.fun = 1; console.log(obj.family.son.fun, copyObj.family.son.fun);
数组:ES3、ES5、ES6以及ES7操作数组方法
var arr = [1, 2, 'str', 4, false, { }, 7, [], 9, function () { }, 0, undefined, -10, null] // ES3: // join(); 连接元素,将数组转化为字符串,不改变原数组 var arr1 = arr.join(""); // 12str4false[object Object]79function(){}0-10 // reverse(); 将数组中的元素颠倒顺序,改变原来的数组 arr.reverse(); // [null, -10, undefined, 0, ƒ, 9, Array(0), 7, {…}, false, 4, "str", 2, 1] // sort(); 将数组的元素按照一定规则排序,改变原来的数组 arr.sort(function (a, b) { return a - b; }); // [-10, null, 0, ƒ, Array(0), false, 1, 2, 4, 7, 9, {…}, "str", undefined] arr.sort(function (a, b) { return b - a; }); // [9, 7, 4, 2, 1, null, 0, false, -10, ƒ, Array(0), {…}, "str", undefined] // concat(); 将参数(参数不限)粘合在数组后面,不改变原数组 var arr1 = arr.concat([1, 2, 3, 4]); // [9, 7, 4, 2, 1, null, 0, Array(0), -10, ƒ, false, {…}, "str", undefined, 1, 2, 3, 4] var arr1 = arr.concat(function () { }, 123); // [9, 7, 4, 2, 1, null, 0, Array(0), -10, ƒ, false, {…}, "str", undefined, ƒ, 123] // slice(); 返回数组的一个片段或子数组,不改变原数组 var arr1 = arr.slice(2, 4); // [4, 2] 从第2位(包含第2位)截取到第4位(不包含第4位) // splice(index,howmany,item1,.....,itemX); 从数组中删除元素、插入元素、或者同时完成这俩种操作,改变原来的数组 // index 必需。整数,规定添加/删除项目的位置,使用负数可从数组结尾处规定位置。 // howmany 必需。要删除的项目数量。如果设置为 0,则不会删除项目。数字大于等于index才有效 // item1, ..., itemX 可选。向数组添加的新项目。 arr.splice(2, 0); // [9, 7, 4, 2, 1, null, 0, Array(0), -10, ƒ, false, {…}, "str", undefined] arr.splice(2, 0, "ProsperLee"); // [9, 7, "ProsperLee", 4, 2, 1, null, 0, Array(0), -10, ƒ, false, {…}, "str", undefined] 在第2位之前便添加元素,使之成为新的1位 arr.splice(2, 1, "Prosper", "Lee"); // [9, 7, "Prosper", "Lee", 4, 2, 1, null, 0, Array(0), -10, ƒ, false, {…}, "str", undefined] 在第2位之前添加元素,使之成为新的2位 arr.splice(2, 5, "a", "b"); // [9, 7, "a", "b", null, 0, Array(0), -10, ƒ, false, {…}, "str", undefined] 删除第2位到第5+1位 在第2位之前添加元素,使之成为新的2位 // push(); 和 pop(); 向数组中插入或删除元素,改变原来的数组,末尾 // unshift(); 和 shift(); 向数组中插入或删除元素,改变原来的数组,开头 // toString(); 和 toLocaleString(); 将数组的每个方法转化为字符串,并且输出用逗号分隔的字符串列表,不改变原数组 var arr1 = arr.toString(); // 9,7,a,b,,0,,-10,function () { },false,[object Object],str, var arr1 = arr.toLocaleString(); // 9,7,a,b,,0,,-10,function () { },false,[object Object],str, console.log(arr); console.log(arr1); // ------------------------------------------------------------------------------------------------------------------------------------- var arr = [1, 2, 'str', 4, false, { }, 7, [], 9, function () { }, 0, undefined, -10, null] // ES5: // map(); 将数组的每个元素传递给指定的函数,并返回一个数组,它包含该函数的返回值,不改变原数组,返回一个新数组 var map1 = arr.map(function (x) { return x * 2; }); // [2, 4, NaN, 8, 0, NaN, 14, 0, 18, NaN, 0, NaN, -20, 0] var newArr = [function () { return [1, 2] }, function () { return true }, function () { return 'abc' }] var newMap = newArr.map(function (x) { return x(); }) // 返回的时 x()的结果 [Array(2), true, "abc"] // filter(); 数组真假过滤器,将数组的每个元素传递给指定的函数,并返回一个数组,它包含该函数,不改变原数组,返回一个新数组 var newArr1 = [function a() { return [1, 2] }, function b() { return false }, function c() { return 'abc' }] var newMap1 = newArr1.filter(function (x) { return x(); }) // 判断x()真假,返回x [function a() { return [1, 2] }, function c() { return 'abc' }] // every(); 和 some(); 对数组元素应用指定的函数判定(对于空数组,every() 返回true, some()返回 false) arr.every(function (x) { return x != 123; }); // true arr中的每一项都不等于123? arr.every(function (x) { return x != 1; }); // false arr中的每一项都不等于1? arr.some(function (x) { return x != 1; }); // true arr中有没有不等于1的项? arr.some(function (x) { return x instanceof Object; }); // false arr中有没有不是对象的项? // reduce(); 和 reduceRight(); 使用指定的函数将数组元素进行组合,生成单个值,reduce从左加到右,reduceRight相反 var a = [1,3,5,2] a.reduce(function (a, b) { return a - b; }); // -9 a.reduce(function (a, b) { return -a - b; }); // -1 -(-(-1-3)-5)-2 a.reduceRight(function (a, b) { return a + b; }); // 11 2+5+3+1 // 整理字符串数组为对象格式(比如: a.b.c.d ---> [a,b,c,d] ---> [d,c,b,a] ---> {a:{b:{c:{d:null}}}}) let keys = 'a.b.c.d'.split('.'); let obj = keys.reverse().reduce((p, c) => ({ [c]: p }), null); // indexOf(); 和 lastIndexOf(); 搜索数组中具有给定值的元素,返回该元素索引,lastIndexOf() 指从前往后查询. lastIndexOf() 指从后往前查询 // 第一个参数指的是需要搜索的值,返回则找到第一个元素的索引或者如果没有找到就返回-1 // 第二个参数是可选的,它指定数组中的一个索引,表示从哪里开始搜索,可以是负数,它代表相对于数组末尾的个数。最后一个元素是-1 arr.indexOf(-1); // -1 arr.indexOf(1); // 0 arr.indexOf(null); // 13 arr.indexOf(2,2); // -1 从第二位开始找 arr.indexOf(2,1); // 1 从第一位开始找 // ------------------------------------------------------------------------------------------------------------------------------------- var arr = [1, 2, 'str', 4, false, { }, 7, [], 9, function () { }, 0, undefined, -10, null] // ES6: // Array.from(); 将类数组对象和可遍历对象转化为数组,浅拷贝 var a = "ProsperLee"; // 类数组 Array.from(a); // ["P", "r", "o", "s", "p", "e", "r", "L", "e", "e"] // Array.of(); 将一组值转化为数组。 Array.of(a); // ["ProsperLee"] Array(a); // ["ProsperLee"] Array.of(5); // [5] Array(5); // [empty × 5] // copyWithin(target,start,end); 在数组内部,将指定位置的成员复制到其他位置(会覆盖原有成员).改变原数组 // target(必须): 从该位置开始替换数据. // start(可选):从该位置开始读取数据. // end(可选):到该位置的前一个位置. var a = ['a', 'b', 'c', 'd', 'e', 'f']; a.copyWithin(2); // ["a", "b", "a", "b", "c", "d"] 从第二位置开始替换,替换成a数组从左到右(从0到a.length-2-1)的各各元素,不能超出数组长度 var a = ['a', 'b', 'c', 'd', 'e', 'f']; a.copyWithin(2, 1, 5); // ["a", "b", "b", "c", "d", "e"] 从第二位置开始替换,替换成a数组从左到右(从1到5)的各各元素,不能超出数组长度 // find();返回数组中满足提供的测试函数的第一个元素的值。否则返回 undefined arr.find(function(el){ return Boolean(el); }) // 1 arr.find(function(el){ return !Boolean(el); }) // false arr.find(function(el){ return el == 123; }) // undefined // findIndex(); 返回数组中满足提供的测试函数的第一个元素的索引。否则返回-1。 arr.findIndex(function(el){ return el == 123; }) // -1 arr.findIndex(function(el){ return el == 7; }) // 6 // fill(value,start,end); 从start开始填充value,填充到end-1位置结束,最大填充为数组长度.改变原数组 var arr = [1, 2, 'str', 4, false, { }, 7, [], 9, function () { }, 0, undefined, -10, null] arr.fill(0,0,13) // [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, null] var arr = [1, 2, 'str', 4, false, { }, 7, [], 9, function () { }, 0, undefined, -10, null] arr.fill(0,5,8) // [1, 2, "str", 4, false, 0, 0, 0, 9, ƒ, 0, undefined, -10, null] // ------------------------------------------------------------------------------------------------------------------------------------- var arr = [1, 2, 'str', 4, false, { }, 7, [], 9, function () { }, 0, undefined, -10, null] // ES7: // includes(); 判断一个数组是否包含一个指定的值,根据情况,如果包含则返回 true,否则返回false console.log(arr.includes(123)); // false console.log(arr.includes('str')); // true
数组去重
Array.prototype.unique = function () { var temp = { }; var arr = []; var len = this.length; for (var i = 0; i < len; i++) { if(!temp[this[i]]){ temp[this[i]] = 'a'; arr.push(this[i]) } } return arr; } var arr = ['abc', 12, 5, 'abc', 1, 23, 5]; console.log(arr.unique()); // ["abc", 12, 5, 1, 23]
命名空间
- 1:使用with的语句很难优化。
- 2:使用with语句速度要比不使用with语句的等价代码的速度慢得多。
- 3:在with语句中的函数定义和变量初始化可能产生令人惊讶,和直觉相抵触的行为。
- 4:90%(或者更高比例)的with应用场景都可以用其他更好的方式代替。
var obj = { A:{ Lee:{ name: 'Lee' }, Zhang:{ name: 'Zhang' } }, B:{ Zhang:{ }, Zhao:{ } } } with(obj.A.Lee.name){ console.log(name); // Lee }
严格模式 'use strict'
- 不能使用 caller, callee, with
- 变量必需声明
- 拒绝重复属性和方法