Array
数组遍历
for循环
以正确响应break、continue和return语句
for(let i = 0,i<len,i++){
//执行
}
forEach
遍历数组的每一项,没有返回值,对原数组没影响,不支持IE,不能使用中断循环语句。!!遍历数组会自动跳过空元素!!
fruits.forEach(function (item, index, array) {
console.log(item, index);
});
map
有返回值,可以return出来map的回调函数中支持return返回值;return的是啥,相当于把数组中的这一项变为啥(并不影响原来的数组,只是相当于把原数组克隆一份,把克隆的这一份的数组中的对应项改变了)
arr.map(function(value,index,array){
//do something
return XXX
})
var ary = [12,23,24,42,1];
var res = ary.map(function (item,index,ary ) {
return item*10;
})
console.log(res);//-->[120,230,240,420,10]; 原数组拷贝了一份,并进行了修改
console.log(ary);//-->[12,23,24,42,1]; 原数组并未发生变化
for of
以正确响应break、continue和return语句
for (var value of myArray) {
console.log(value);
}
filter
不会改变原数组,返回新数组
var arr = [
{ id: 1, text: 'aa', done: true },
{ id: 2, text: 'bb', done: false }
]
console.log(arr.filter(item => item.done))
转为ES5
arr.filter(function (item) {
return item.done;
});
var arr = [73,84,56, 22,100]
var newArr = arr.filter(item => item>80) //得到新数组 [84, 100]
console.log(newArr,arr)
every
every()是对数组中的每一项运行给定函数,如果该函数对每一项返回true,则返回true。
var arr = [ 1, 2, 3, 4, 5, 6 ];
console.log( arr.every( function( item, index, array ){
return item > 3;
})); //返回false
some
some()是对数组中每一项运行指定函数,如果该函数对任一项返回true,则返回true。
var arr = [ 1, 2, 3, 4, 5, 6 ];
console.log( arr.some( function( item, index, array ){
return item > 3;
})); //返回true
reduce
reduce() 方法接收一个函数作为累加器(accumulator),数组中的每个值(从左到右)开始缩减,最终为一个值。
var total = [0,1,2,3,4].reduce((a, b)=>a + b); //10
reduce接受一个函数,函数有四个参数,分别是:上一次的值,当前值,当前值的索引,数组.
[0, 1, 2, 3, 4].reduce(function(previousValue, currentValue, index, array){ return previousValue + currentValue;});
reduceRight
reduceRight()方法的功能和reduce()功能是一样的,不同的是reduceRight()从数组的末尾向前将数组中的数组项做累加。
reduceRight()首次调用回调函数callbackfn时,prevValue 和 curValue 可以是两个值之一。如果调用 reduceRight() 时提供了 initialValue 参数,则 prevValue 等于 initialValue,curValue 等于数组中的最后一个值。如果没有提供 initialValue 参数,则 prevValue 等于数组最后一个值, curValue 等于数组中倒数第二个值。
var arr = [0,1,2,3,4];arr.reduceRight(function (preValue,curValue,index,array) { return preValue + curValue;}); // 10
find
find()方法返回数组中符合测试函数条件的第一个元素。否则返回undefined
var stu = [{name: '张三',gender: '男',age: 20},{name: '王小毛',gender: '男',age: 20},{name: '李四',gender:'男',age: 20}];function getStu(element){ return element.name == '李四'}stu.find(getStu)//返回结果为//{name: "李四", gender: "男", age: 20}ES6方法stu.find((element) => (element.name == '李四'))
findIndex
对于数组中的每个元素,findIndex 方法都会调用一次回调函数(采用升序索引顺序),直到有元素返回 true。只要有一个元素返回 true,findIndex 立即返回该返回 true 的元素的索引值。如果数组中没有任何元素返回 true,则 findIndex 返回 -1。
findIndex 不会改变数组对象。
[1,2,3].findIndex(function(x) { x == 2; });// 返回索引值1[1,2,3].findIndex(x => x == 4);// 返回索引值 -1.
keys/values(Symbol.iterator])/entries
都返回一个遍历器对象,可以用for…of循环进行遍历,区别是keys()是对键名的遍历、values()是对键值的遍历,entries()是对键值对的遍历
for (let index of ['a', 'b'].keys()) { console.log(index);//0 1}//valuesfor (let elem of ['a', 'b'].values()) { console.log(elem); // 'a' 'b'}//entriesfor (let [index, elem] of ['a', 'b'].entries()) { console.log(index, elem); //0'a' 1'b'}//Symbol.iteratorvar arr = ['a', 'b', 'c', 'd', 'e'];var eArr = arr[Symbol.iterator]();// 浏览器必须支持 for...of 循环for (let letter of eArr) { console.log(letter);}var arr = ['a', 'b', 'c', 'd', 'e'];var eArr = arr[Symbol.iterator]();console.log(eArr.next().value); // aconsole.log(eArr.next().value); // bconsole.log(eArr.next().value); // cconsole.log(eArr.next().value); // dconsole.log(eArr.next().value); // e
copyWithin
浅复制数组的一部分到同一数组中的另一个位置,并返回它,不会改变原数组的长度。参数 target、start 和 end 必须为整数。
[1, 2, 3, 4, 5].copyWithin(-2)// [1, 2, 3, 1, 2][1, 2, 3, 4, 5].copyWithin(0, 3)// [4, 5, 3, 4, 5][1, 2, 3, 4, 5].copyWithin(0, 3, 4)// [4, 2, 3, 4, 5][1, 2, 3, 4, 5].copyWithin(-2, -3, -1)// [1, 2, 3, 3, 4][].copyWithin.call({length: 5, 3: 1}, 0, 3);// {0: 1, 3: 1, length: 5}// ES2015 Typed Arrays are subclasses of Arrayvar i32a = new Int32Array([1, 2, 3, 4, 5]);i32a.copyWithin(0, 2);// Int32Array [3, 4, 5, 4, 5]// On platforms that are not yet ES2015 compliant:[].copyWithin.call(new Int32Array([1, 2, 3, 4, 5]), 0, 3, 4);// Int32Array [4, 2, 3, 4, 5]
fill(value[, start[, end]])
用一个固定值填充一个数组中从起始索引到终止索引内的全部元素。不包括终止索引。
[1, 2, 3].fill(4); // [4, 4, 4][1, 2, 3].fill(4, 1); // [1, 4, 4][1, 2, 3].fill(4, 1, 2); // [1, 4, 3][1, 2, 3].fill(4, 1, 1); // [1, 2, 3][1, 2, 3].fill(4, 3, 3); // [1, 2, 3][1, 2, 3].fill(4, -3, -2); // [4, 2, 3][1, 2, 3].fill(4, NaN, NaN); // [1, 2, 3][1, 2, 3].fill(4, 3, 5); // [1, 2, 3]Array(3).fill(4); // [4, 4, 4][].fill.call({ length: 3 }, 4); // {0: 4, 1: 4, 2: 4, length: 3}// Objects by reference.var arr = Array(3).fill({}) // [{}, {}, {}];// 需要注意如果fill的参数为引用类型,会导致都执行都一个引用类型// 如 arr[0] === arr[1] 为truearr[0].hi = "hi"; // [{ hi: "hi" }, { hi: "hi" }, { hi: "hi" }]
includes
判断一个数组是否包含一个指定的值,根据情况,如果包含则返回 true,否则返回false。
[1, 2, 3].includes(2); // true[1, 2, 3].includes(4); // false[1, 2, 3].includes(3, 3); // false[1, 2, 3].includes(3, -1); // true[1, 2, NaN].includes(NaN); // true
flat
会按照一个可指定的深度递归遍历数组,并将所有元素与遍历到的子数组中的元素合并为一个新数组返回。
var arr1 = [1, 2, [3, 4]];arr1.flat();// [1, 2, 3, 4]var arr2 = [1, 2, [3, 4, [5, 6]]];arr2.flat();// [1, 2, 3, 4, [5, 6]]var arr3 = [1, 2, [3, 4, [5, 6]]];arr3.flat(2);// [1, 2, 3, 4, 5, 6]//使用 Infinity,可展开任意深度的嵌套数组var arr4 = [1, 2, [3, 4, [5, 6, [7, 8, [9, 10]]]]];arr4.flat(Infinity);// [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
flatMap
使用映射函数映射每个元素,然后将结果压缩成一个新数组。它与 map 连着深度值为1的 flat 几乎相同,但 flatMap
通常在合并成一种方法的效率稍微高一些。
var arr1 = [1, 2, 3, 4];arr1.map(x => [x * 2]);// [[2], [4], [6], [8]]arr1.flatMap(x => [x * 2]);// [2, 4, 6, 8]// only one level is flattenedarr1.flatMap(x => [[x * 2]]);// [[2], [4], [6], [8]]let arr1 = ["it's Sunny in", "", "California"];arr1.map(x => x.split(" "));// [["it's","Sunny","in"],[""],["California"]]arr1.flatMap(x => x.split(" "));// ["it's","Sunny","in", "", "California"]
静态方法
Array.from()
从一个类似数组或可迭代对象创建一个新的,浅拷贝的数组实例。
console.log(Array.from('foo'));// expected output: Array ["f", "o", "o"]console.log(Array.from([1, 2, 3], x => x + x));// expected output: Array [2, 4, 6]
Array.isArray()
确定传递的值是否是一个 Array
Array.isArray([1, 2, 3]);// trueArray.isArray({foo: 123});// falseArray.isArray("foobar");// falseArray.isArray(undefined);// false
Array.of()
创建一个具有可变数量参数的新数组实例,而不考虑参数的数量或类型。
**Array.of()**
和 **Array**
构造函数之间的区别在于处理整数参数:**Array.of(7)**
创建一个具有单个元素 7 的数组,而 Array(7)
创建一个长度为7的空数组(注意:这是指一个有7个空位(empty)的数组,而不是由7个undefined
组成的数组)。
Array.of(7); // [7]Array.of(1, 2, 3); // [1, 2, 3]Array(7); // [empty ,empty ,empty ,empty ,empty ,empty ,empty ]Array(1, 2, 3); // [1, 2, 3]
非静态方法
pop()
从数组中删除最后一个元素,并返回该元素的值。此方法更改数组的长度。
push()
将一个或多个元素添加到数组的末尾,并返回该数组的新长度。
shift()
从数组中删除第一个元素,并返回该元素的值。此方法更改数组的长度。
unshift()
将一个或多个元素添加到数组的开头,并返回该数组的新长度(该方法修改原有数组**)**。
concat()
合并两个或多个数组。此方法不会更改现有数组,而是返回一个新数组。
注意:数组/值在连接时保持不变。此外,对于新数组的任何操作(仅当元素不是对象引用时)都不会对原始数组产生影响,反之亦然。
const array1 = ['a', 'b', 'c'];const array2 = ['d', 'e', 'f'];const array3 = array1.concat(array2);console.log(array3);// expected output: Array ["a", "b", "c", "d", "e", "f"]
join()
将一个数组(或一个类数组对象)的所有元素连接成一个字符串并返回这个字符串。如果数组只有一个项目,那么将返回该项目而不使用分隔符
const elements = ['Fire', 'Air', 'Water'];console.log(elements.join());// expected output: "Fire,Air,Water"//如果一个元素为 undefined 或 null,它会被转换为空字符串。console.log(elements.join(''));// expected output: "FireAirWater"console.log(elements.join('-'));// expected output: "Fire-Air-Water"function f(a, b, c) { var s = Array.prototype.join.call(arguments); console.log(s); // '1,a,true'}f(1, 'a', true);
lastIndexOf()
返回指定元素(也即有效的 JavaScript 值或变量)在数组中的最后一个的索引,如果不存在则返回 -1。从数组的后面向前查找,从 fromIndex
处开始。
const animals = ['Dodo', 'Tiger', 'Penguin', 'Dodo'];console.log(animals.lastIndexOf('Dodo'));// expected output: 3console.log(animals.lastIndexOf('Tiger'));// expected output: 1
reverse()
将数组中元素的位置颠倒,并返回该数组。数组的第一个元素会变成最后一个,数组的最后一个元素变成第一个。该方法会改变原数组。
const array1 = ['one', 2,'two', 'three'];array1.reverse()//(4) ["three", "two", 2, "one"]
slice()
返回一个新的数组对象,这一对象是一个由 begin
和 end
决定的原数组的浅拷贝(包括 begin
,不包括end
)。原始数组不会被改变。
const animals = ['ant', 'bison', 'camel', 'duck', 'elephant'];console.log(animals.slice(2));// expected output: Array ["camel", "duck", "elephant"]console.log(animals.slice(2, 4));// expected output: Array ["camel", "duck"]console.log(animals.slice(1, 5));// expected output: Array ["bison", "camel", "duck", "elephant"]console.log(animals.slice(-2));// expected output: Array ["duck", "elephant"]console.log(animals.slice(2, -1));// expected output: Array ["camel", "duck"]
sort()
用原地算法对数组的元素进行排序,并返回数组。默认排序顺序是在将元素转换为字符串,然后比较它们的UTF-16代码单元值序列时构建的
由于它取决于具体实现,因此无法保证排序的时间和空间复杂性。
var numbers = [4, 2, 5, 1, 3];numbers.sort(function(a, b) { return a - b;});console.log(numbers);也可以写成:var numbers = [4, 2, 5, 1, 3];numbers.sort((a, b) => a - b);console.log(numbers);// [1, 2, 3, 4, 5]
splice()
通过删除或替换现有元素或者原地添加新的元素来修改数组,并以数组形式返回被修改的内容。此方法会改变原数组。
const months = ['Jan', 'March', 'April', 'June'];months.splice(1, 0, 'Feb');// inserts at index 1console.log(months);// expected output: Array ["Jan", "Feb", "March", "April", "June"]months.splice(4, 1, 'May');// replaces 1 element at index 4console.log(months);// expected output: Array ["Jan", "Feb", "March", "April", "May"]
toLocaleString()
返回一个字符串表示数组中的元素。数组中的元素将使用各自的 toLocaleString
方法转成字符串,这些字符串将使用一个特定语言环境的字符串(例如一个逗号 “,”)隔开。
const array1 = [1, 'a', new Date('21 Dec 1997 14:12:00 UTC')];const localeString = array1.toLocaleString('en', { timeZone: 'UTC' });console.log(localeString);// expected output: "1,a,12/21/1997, 2:12:00 PM",
toString()
返回一个字符串,表示指定的数组及其元素。
const array1 = [1, 2, 'a', '1a'];console.log(array1.toString());// expected output: "1,2,a,1a"
String
字符串分割
slice
提取某个字符串的一部分,并返回一个新的字符串,且不会改动原字符串。
const str = 'The quick brown fox jumps over the lazy dog.';console.log(str.slice(31));// expected output: "the lazy dog."console.log(str.slice(4, 19));// expected output: "quick brown fox"console.log(str.slice(-4));// expected output: "dog."console.log(str.slice(-9, -5));// expected output: "lazy"
substring()
返回一个字符串在开始索引到结束索引之间的一个子集, 或从开始索引直到字符串的末尾的一个子集。
var anyString = "Mozilla";// 输出 "Moz"console.log(anyString.substring(0,3));console.log(anyString.substring(3,0));console.log(anyString.substring(3,-3));console.log(anyString.substring(3,NaN));console.log(anyString.substring(-2,3));console.log(anyString.substring(NaN,3));
split()
指定的分隔符字符串将一个String
对象分割成子字符串数组,以一个指定的分割字串来决定每个拆分的位置。**(支持正则)**
const str = 'The quick brown fox jumps over the lazy dog.';const words = str.split(' ');console.log(words[3]);// expected output: "fox"const chars = str.split('');console.log(chars[8]);// expected output: "k"const strCopy = str.split();console.log(strCopy);// expected output: Array ["The quick brown fox jumps over the lazy dog."]
字符串查询
indexOf()
返回调用它的 String
对象中第一次出现的指定值的索引,从 fromIndex
处进行搜索。如果未找到该值,则返回 -1。
const paragraph = 'The quick brown fox jumps over the lazy dog. If the dog barked, was it really lazy?';const searchTerm = 'dog';const indexOfFirst = paragraph.indexOf(searchTerm);console.log(`The index of the first "${searchTerm}" from the beginning is ${indexOfFirst}`);// expected output: "The index of the first "dog" from the beginning is 40"
charAt()
从一个字符串中返回指定的字符。
str.charAt(index)
charCodeAt()加密解密
返回 0
到 65535
之间的整数,表示给定索引处的 UTF-16 代码单元
const sentence = 'The quick brown fox jumps over the lazy dog.';const index = 4;console.log(`The character code ${sentence.charCodeAt(index)} is equal to ${sentence.charAt(index)}`);// expected output: "The character code 113 is equal to q"
codePointAt()加密解密
返回 一个 Unicode 编码点值的非负整数。
'ABC'.codePointAt(1); // 66'\uD800\uDC00'.codePointAt(0); // 65536'XYZ'.codePointAt(42); // undefined
startsWith()
判断当前字符串是否以另外一个给定的子字符串开头,并根据判断结果返回 true
或 false
。
const str1 = 'Saturday night plans';console.log(str1.startsWith('Sat'));// expected output: trueconsole.log(str1.startsWith('Sat', 3));// expected output: false
endsWith()
判断当前字符串是否是以另外一个给定的子字符串“结尾”的,根据判断结果返回 true
或 false
。
const str1 = 'Cats are the best!';console.log(str1.endsWith('best', 17));// expected output: trueconst str2 = 'Is this a question';console.log(str2.endsWith('?'));// expected output: false
includes()
判断一个字符串是否包含在另一个字符串中,根据情况返回 true 或 false。区分大小写
'Blue Whale'.includes('blue'); // returns false
lastIndexOf()
返回调用String
对象的指定值最后一次出现的索引,在一个字符串中的指定位置 fromIndex
处从后向前搜索。如果没找到这个特定值则返回-1 。
该方法将从尾到头地检索字符串 str,看它是否含有子串 searchValue。开始检索的位置在字符串的 fromIndex 处或字符串的结尾(没有指定 fromIndex 时)。如果找到一个 searchValue,则返回 searchValue 的第一个字符在 str 中的位置。str中的字符位置是从 0 开始的。
'canal'.lastIndexOf('a'); // returns 3 (没有指明fromIndex则从末尾l处开始反向检索到的第一个a出现在l的后面,即index为3的位置)'canal'.lastIndexOf('a', 2); // returns 1(指明fromIndex为2则从n处反向向回检索到其后面就是a,即index为1的位置)'canal'.lastIndexOf('a', 0); // returns -1(指明fromIndex为0则从c处向左回向检索a发现没有,故返回-1)'canal'.lastIndexOf('x'); // returns -1'canal'.lastIndexOf('c', -5); // returns 0(指明fromIndex为-5则视同0,从c处向左回向查找发现自己就是,故返回0)'canal'.lastIndexOf('c', 0); // returns 0(指明fromIndex为0则从c处向左回向查找c发现自己就是,故返回自己的索引0)'canal'.lastIndexOf(''); // returns 5'canal'.lastIndexOf('', 2); // returns 2
localeCompare()(不常用)
返回一个数字来指示一个参考字符串是否在排序顺序前面或之后或与给定字符串相同
字符串正则查询
match()
检索返回一个字符串匹配正则表达式的结果。
const paragraph = 'The quick brown fox jumps over the lazy dog. It barked.';const regex = /[A-Z]/g;const found = paragraph.match(regex);console.log(found);// expected output: Array ["T", "I"]
matchAll()
返回一个包含所有匹配正则表达式的结果及分组捕获组的迭代器。
const regexp = /t(e)(st(\d?))/g;const str = 'test1test2';const array = [...str.matchAll(regexp)];console.log(array[0]);// expected output: Array ["test1", "e", "st1", "1"]console.log(array[1]);// expected output: Array ["test2", "e", "st2", "2"]
normalize()
按照指定的一种 Unicode 正规形式将当前字符串正规化。(如果该值不是字符串,则首先将其转换为一个字符串)。
search()
执行正则表达式和 String
对象之间的一个搜索匹配。
const paragraph = 'The quick brown fox jumps over the lazy dog. If the dog barked, was it really lazy?';// any character that is not a word character or whitespaceconst regex = /[^\w\s]/g;console.log(paragraph.search(regex));// expected output: 43console.log(paragraph[paragraph.search(regex)]);// expected output: "."
字符串填充
padEnd()
用另一个字符串填充当前字符串(如果需要的话则重复填充),返回填充后达到指定长度的字符串。从当前字符串的末尾(右侧)开始填充。
const str1 = 'Breaded Mushrooms';console.log(str1.padEnd(25, '.'));// expected output: "Breaded Mushrooms........"const str2 = '200';console.log(str2.padEnd(5));// expected output: "200 "
padStart()
用另一个字符串填充当前字符串(如果需要的话,会重复多次),以便产生的字符串达到给定的长度。从当前字符串的左侧开始填充。
const str1 = '5';console.log(str1.padStart(2, '0'));// expected output: "05"const fullNumber = '2034399002125581';const last4Digits = fullNumber.slice(-4);const maskedNumber = last4Digits.padStart(fullNumber.length, '*');console.log(maskedNumber);// expected output: "************5581"
repeat()
构造并返回一个新字符串,该字符串包含被连接在一起的指定数量的字符串的副本。
var str = "Runoob";str.repeat(2);//RunoobRunoob
字符串替换
replace()
反回一个由替换值(replacement
)替换部分或所有的模式(pattern
)匹配项后的新字符串。模式可以是一个字符串或者一个正则表达式,替换值可以是一个字符串或者一个每次匹配都要调用的回调函数。如果pattern
是字符串,则仅替换第一个匹配项
const p = 'The quick brown fox jumps over the lazy dog. If the dog reacted, was it really lazy?';console.log(p.replace('dog', 'monkey'));// expected output: "The quick brown fox jumps over the lazy monkey. If the dog reacted, was it really lazy?"const regex = /Dog/i;console.log(p.replace(regex, 'ferret'));// expected output: "The quick brown fox jumps over the lazy ferret. If the dog reacted, was it really lazy?"
replaceAll()
返回一个新字符串,新字符串所有满足 pattern
的部分都已被replacement
替换。pattern
可以是一个字符串或一个 RegExp
, replacement
可以是一个字符串或一个在每次匹配被调用的函数。
const p = 'The quick brown fox jumps over the lazy dog. If the dog reacted, was it really lazy?';console.log(p.replaceAll('dog', 'monkey'));// expected output: "The quick brown fox jumps over the lazy monkey. If the monkey reacted, was it really lazy?"// global flag required when calling replaceAll with regexconst regex = /Dog/ig;console.log(p.replaceAll(regex, 'ferret'));// expected output: "The quick brown fox jumps over the lazy ferret. If the ferret reacted, was it really lazy?"
trim()/trimRight()/trimStart()
从一个字符串的两端删除空白字符。在这个上下文中的空白字符是所有的空白字符 (space, tab, no-break space 等) 以及所有行终止符字符(如 LF,CR等)。
const greeting = ' Hello world! ';console.log(greeting);// expected output: " Hello world! ";console.log(greeting.trim());// expected output: "Hello world!";const greeting = ' Hello world! ';console.log(greeting);// expected output: " Hello world! ";console.log(greeting.trimEnd());// expected output: " Hello world!";const greeting = ' Hello world! ';console.log(greeting);// expected output: " Hello world! ";console.log(greeting.trimStart());// expected output: "Hello world! ";
Object
静态方法
Object.assign()
通过复制一个或多个对象来创建一个新的对象。会改变第一个对象,返回新对象
const target = { a: 1, b: 2 };const source = { b: 4, c: 5 };const returnedTarget = Object.assign(target, source);console.log(target);// expected output: Object { a: 1, b: 4, c: 5 }console.log(returnedTarget);// expected output: Object { a: 1, b: 4, c: 5 }
Object.create()
创建一个新对象,使用现有的对象来提供新创建的对象的__proto__
。
const person = { isHuman: false, printIntroduction: function() { console.log(`My name is ${this.name}. Am I human? ${this.isHuman}`); }};const me = Object.create(person);me.name = 'Matthew'; // "name" is a property set on "me", but not on "person"me.isHuman = true; // inherited properties can be overwrittenme.printIntroduction();// expected output: "My name is Matthew. Am I human? true"
Object.defineProperties()
在一个对象上定义新的属性或修改现有属性,并返回该对象。
var obj = {};Object.defineProperties(obj, { 'property1': { value: true, writable: true }, 'property2': { value: 'Hello', writable: false } // etc. etc.});
Object.defineProperty()
直接在一个对象上定义一个新属性,或者修改一个对象的现有属性,并返回此对象。
const object1 = {};Object.defineProperty(object1, 'property1', { value: 42, writable: false});object1.property1 = 77;// throws an error in strict modeconsole.log(object1.property1);// expected output: 42
Object.entries()
返回一个给定对象自身可枚举属性的键值对数组,其排列与使用 for...in
循环遍历该对象时返回的顺序一致(区别在于 for-in 循环还会枚举原型链中的属性)。
const object1 = { a: 'somestring', b: 42};for (const [key, value] of Object.entries(object1)) { console.log(`${key}: ${value}`);}// expected output:// "a: somestring"// "b: 42"
Object.freeze()
可以冻结一个对象。一个被冻结的对象再也不能被修改;冻结了一个对象则不能向这个对象添加新的属性,不能删除已有属性,不能修改该对象已有属性的可枚举性、可配置性、可写性,以及不能修改已有属性的值。此外,冻结一个对象后该对象的原型也不能被修改。freeze()
返回和传入的参数相同的对象。
const obj = { prop: 42};Object.freeze(obj);obj.prop = 33;// Throws an error in strict modeconsole.log(obj.prop);// expected output: 42
Object.fromEntries()
把键值对列表转换为一个对象。
const entries = new Map([ ['foo', 'bar'], ['baz', 42]]);const obj = Object.fromEntries(entries);console.log(obj);// expected output: Object { foo: "bar", baz: 42 }
Object.getOwnPropertyDescriptor()
返回指定对象上一个自有属性对应的属性描述符。(自有属性指的是直接赋予该对象的属性,不需要从原型链上进行查找的属性)
const object1 = { property1: 42};const descriptor1 = Object.getOwnPropertyDescriptor(object1, 'property1');console.log(descriptor1.configurable);// expected output: trueconsole.log(descriptor1.value);// expected output: 42
Object.getOwnPropertyDescriptors()
来获取一个对象的所有自身属性的描述符。
Object.getOwnPropertyNames()
返回一个由指定对象的所有自身属性的属性名(包括不可枚举属性但不包括Symbol值作为名称的属性)组成的数组。
var arr = ["a", "b", "c"];console.log(Object.getOwnPropertyNames(arr).sort()); // ["0", "1", "2", "length"]// 类数组对象var obj = { 0: "a", 1: "b", 2: "c"};console.log(Object.getOwnPropertyNames(obj).sort()); // ["0", "1", "2"]// 使用Array.forEach输出属性名和属性值Object.getOwnPropertyNames(obj).forEach(function(val, idx, array) { console.log(val + " -> " + obj[val]);});// 输出// 0 -> a// 1 -> b// 2 -> c//不可枚举属性var my_obj = Object.create({}, { getFoo: { value: function() { return this.foo; }, enumerable: false }});my_obj.foo = 1;console.log(Object.getOwnPropertyNames(my_obj).sort()); // ["foo", "getFoo"]
Object.getOwnPropertySymbols()
返回一个给定对象自身的所有 Symbol 属性的数组。
var obj = {};var a = Symbol("a");var b = Symbol.for("b");obj[a] = "localSymbol";obj[b] = "globalSymbol";var objectSymbols = Object.getOwnPropertySymbols(obj);console.log(objectSymbols.length); // 2console.log(objectSymbols) // [Symbol(a), Symbol(b)]console.log(objectSymbols[0]) // Symbol(a)
Object.getPrototypeOf()
返回指定对象的原型(内部[[Prototype]]
属性的值)。
const prototype1 = {};const object1 = Object.create(prototype1);console.log(Object.getPrototypeOf(object1) === prototype1);// expected output: true
Object.prototype.hasOwnProperty()
返回一个布尔值,指示对象自身属性中是否具有指定的属性(也就是,是否有指定的键)。
const object1 = {};object1.property1 = 42;console.log(object1.hasOwnProperty('property1'));// expected output: trueconsole.log(object1.hasOwnProperty('toString'));// expected output: falseconsole.log(object1.hasOwnProperty('hasOwnProperty'));// expected output: false
Object.is()
判断两个值是否为同一个值。
Object.is('foo', 'foo'); // trueObject.is(window, window); // trueObject.is('foo', 'bar'); // falseObject.is([], []); // falsevar foo = { a: 1 };var bar = { a: 1 };Object.is(foo, foo); // trueObject.is(foo, bar); // falseObject.is(null, null); // true// 特例Object.is(0, -0); // falseObject.is(0, +0); // trueObject.is(-0, -0); // trueObject.is(NaN, 0/0); // true
Object.isExtensible()
判断一个对象是否是可扩展的(是否可以在它上面添加新的属性)。
// 新对象默认是可扩展的.var empty = {};Object.isExtensible(empty); // === true// ...可以变的不可扩展.Object.preventExtensions(empty);Object.isExtensible(empty); // === false// 密封对象是不可扩展的.var sealed = Object.seal({});Object.isExtensible(sealed); // === false// 冻结对象也是不可扩展.var frozen = Object.freeze({});Object.isExtensible(frozen); // === false
Object.isFrozen()
判断一个对象是否被冻结。
Object.prototype.isPrototypeOf()
测试一个对象是否存在于另一个对象的原型链上。
``isPrototypeOf() 与 [
instanceof](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Operators/instanceof) 运算符不同。在表达式 "
object instanceof AFunction"中,
object的原型链是针对
AFunction.prototype进行检查的,而不是针对
AFunction 本身。
Object.isSealed()
判断一个对象是否被密封。
// 新建的对象默认不是密封的.var empty = {};Object.isSealed(empty); // === false// 如果你把一个空对象变的不可扩展,则它同时也会变成个密封对象.Object.preventExtensions(empty);Object.isSealed(empty); // === true// 但如果这个对象不是空对象,则它不会变成密封对象,因为密封对象的所有自身属性必须是不可配置的.var hasProp = { fee: "fie foe fum" };Object.preventExtensions(hasProp);Object.isSealed(hasProp); // === false// 如果把这个属性变的不可配置,则这个属性也就成了密封对象.Object.defineProperty(hasProp, 'fee', { configurable: false});Object.isSealed(hasProp); // === true// 最简单的方法来生成一个密封对象,当然是使用Object.seal.var sealed = {};Object.seal(sealed);Object.isSealed(sealed); // === true// 一个密封对象同时也是不可扩展的.Object.isExtensible(sealed); // === false// 一个密封对象也可以是一个冻结对象,但不是必须的.Object.isFrozen(sealed); // === true ,所有的属性都是不可写的var s2 = Object.seal({ p: 3 });Object.isFrozen(s2); // === false, 属性"p"可写var s3 = Object.seal({ get p() { return 0; } });Object.isFrozen(s3); // === true ,访问器属性不考虑可写不可写,只考虑是否可配置
Object.keys()
返回一个由一个给定对象的自身可枚举属性组成的数组,数组中属性名的排列顺序和正常循环遍历该对象时返回的顺序一致 。
// simple arrayvar arr = ['a', 'b', 'c'];console.log(Object.keys(arr)); // console: ['0', '1', '2']// array like objectvar obj = { 0: 'a', 1: 'b', 2: 'c' };console.log(Object.keys(obj)); // console: ['0', '1', '2']// array like object with random key orderingvar anObj = { 100: 'a', 2: 'b', 7: 'c' };console.log(Object.keys(anObj)); // console: ['2', '7', '100']// getFoo is a property which isn't enumerablevar myObj = Object.create({}, { getFoo: { value: function () { return this.foo; } }});myObj.foo = 1;console.log(Object.keys(myObj)); // console: ['foo']
Object.preventExtensions()
让一个对象变的不可扩展,也就是永远不能再添加新的属性。
const object1 = {};Object.preventExtensions(object1);try { Object.defineProperty(object1, 'property1', { value: 42 });} catch (e) { console.log(e); // expected output: TypeError: Cannot define property property1, object is not extensible}
Object.prototype.propertyIsEnumerable()
返回一个布尔值,表示指定的属性是否可枚举。
const object1 = {};const array1 = [];object1.property1 = 42;array1[0] = 42;console.log(object1.propertyIsEnumerable('property1'));// expected output: trueconsole.log(array1.propertyIsEnumerable(0));// expected output: trueconsole.log(array1.propertyIsEnumerable('length'));// expected output: false
Object.seal()
封闭一个对象,阻止添加新属性并将所有现有属性标记为不可配置。当前属性的值只要原来是可写的就可以改变。
const object1 = { property1: 42};Object.seal(object1);object1.property1 = 33;console.log(object1.property1);// expected output: 33delete object1.property1; // cannot delete when sealedconsole.log(object1.property1);// expected output: 33
Object.prototype.toString()
返回一个表示该对象的字符串。
function Dog(name) { this.name = name;}const dog1 = new Dog('Gabby');Dog.prototype.toString = function dogToString() { return `${this.name}`;};console.log(dog1.toString());// expected output: "Gabby"
Object.prototype.valueOf()
返回指定对象的原始值。
// Array:返回数组对象本身var array = ["ABC", true, 12, -5];console.log(array.valueOf() === array); // true// Date:当前时间距1970年1月1日午夜的毫秒数var date = new Date(2013, 7, 18, 23, 11, 59, 230);console.log(date.valueOf()); // 1376838719230// Number:返回数字值var num = 15.26540;console.log(num.valueOf()); // 15.2654// 布尔:返回布尔值true或falsevar bool = true;console.log(bool.valueOf() === bool); // true// new一个Boolean对象var newBool = new Boolean(true);// valueOf()返回的是true,两者的值相等console.log(newBool.valueOf() == newBool); // true// 但是不全等,两者类型不相等,前者是boolean类型,后者是object类型console.log(newBool.valueOf() === newBool); // false// Function:返回函数本身function foo(){}console.log( foo.valueOf() === foo ); // truevar foo2 = new Function("x", "y", "return x + y;");console.log( foo2.valueOf() );/*ƒ anonymous(x,y) {return x + y;}*/// Object:返回对象本身var obj = {name: "张三", age: 18};console.log( obj.valueOf() === obj ); // true// String:返回字符串值var str = "http://www.xyz.com";console.log( str.valueOf() === str ); // true// new一个字符串对象var str2 = new String("http://www.xyz.com");// 两者的值相等,但不全等,因为类型不同,前者为string类型,后者为object类型console.log( str2.valueOf() === str2 ); // false
Object.values()
返回一个给定对象自身的所有可枚举属性值的数组,值的顺序与使用for...in
循环的顺序相同 ( 区别在于 for-in 循环枚举原型链中的属性 )。
var obj = { foo: 'bar', baz: 42 };console.log(Object.values(obj)); // ['bar', 42]// array like objectvar obj = { 0: 'a', 1: 'b', 2: 'c' };console.log(Object.values(obj)); // ['a', 'b', 'c']// array like object with random key ordering// when we use numeric keys, the value returned in a numerical order according to the keysvar an_obj = { 100: 'a', 2: 'b', 7: 'c' };console.log(Object.values(an_obj)); // ['b', 'c', 'a']// getFoo is property which isn't enumerablevar my_obj = Object.create({}, { getFoo: { value: function() { return this.foo; } } });my_obj.foo = 'bar';console.log(Object.values(my_obj)); // ['bar']// non-object argument will be coerced to an objectconsole.log(Object.values('foo')); // ['f', 'o', 'o']
Type与Interface
- type 可以声明基本类型别名,联合类型,元组等类型
// 基本类型别名type Name = string// 联合类型interface Dog { wong();}interface Cat { miao();}type Pet = Dog | Cat// 具体定义数组每个位置的类型type PetList = [Dog, Pet]
- type 语句中还可以使用 typeof 获取实例的 类型进行赋值
// 当你想获取一个变量的类型时,使用 typeoflet div = document.createElement('div');type B = typeof divtype StringOrNumber = string | number; type Text = string | { text: string }; type NameLookup = Dictionary<string, Person>; type Callback<T> = (data: T) => void; type Pair<T> = [T, T]; type Coordinates = Pair<number>; type Tree<T> = T | { left: Tree<T>, right: Tree<T> };
interface 能够声明合并
interface User { name: string age: number}interface User { sex: string}/*User 接口为 { name: string age: number sex: string }*/