前言
在当今数字时代,前端技术正日益成为塑造用户体验的关键。我们在开发中需要用到很多js的内置对象的一些属性来帮助我们更快速的进行开发。或许你是刚踏入前端领域的小白,或者是希望深入了解内置对象的开发者,不论你的经验如何,本篇博客都将给你详细的讲解js的内置对象。
🚀 作者简介:程序员小豪,全栈工程师,热爱编程,曾就职于蔚来、腾讯,现就职于某互联网大厂,技术栈:Vue、React、Python、Java
🎈 本文收录于小豪的前端系列专栏,后续还会更新前端入门以及前端面试的一些相关文章,手把手带你从零学习前端到面试找工作,并如果有想进入前端领域工作的同学,这个前端专栏会对你有所帮助,欢迎关注起来呀
🌼 本人也会持续的去关注AIGC以及人工智能领域
的一些动向并总结到博客中,大家感兴趣的可以关注一下我的人工智能专栏
🌊 云原生的入门学习系列,大家有兴趣的可以看一看
本文目录
- 全局对象
- 值属性
- Infinity
- 说明
- 示例
- NaN
- 说明
- 示例
- 值校验
- undefined
- 说明
- 函数属性
- eval
- 语法
- 说明
- 示例
- isNaN
- 语法
- 说明
- 示例
- parseFloat
- 语法
- 示例
- parseInt
- 语法
- 示例
- decodeURI
- 语法
- 示例
- encodeURI
- 语法
- 说明
- 示例
- Object
- 语法
- Object.assign
- 语法
- 描述
- 示例
- 基本示例
- Object.create
- 语法
- 示例
- 类式继承
- Object.defineProperties
- 语法
- 示例
- Object.defineProperty
- 语法
- 示例
- 对象属性劫持
- Object.entries
- 语法
- 方法说明
- 代码示例
- Object.entries
- 语法
- 方法说明
- 代码示例
- Object.getOwnPropertyDescriptor
- 语法
- 示例
- Object.getOwnPropertyDescriptors
- 语法
- 代码示例
- Object.getPrototypeOf
- 语法
- 示例
- 基本示例
- 标准内置对象
- Object.is
- 语法
- 描述
- 示例
- Object.keys
- 语法
- 描述
- 示例
- 数组
- 类数组
- 不可枚举属性
- Object.setPrototypeOf
- 语法
- 示例
- 代码实现
- Object.values
- 语法
- 方法说明
- 代码示例
- Object.prototype.hasOwnProperty
- 语法
- 描述
- 示例
- 基本示例
- 自有属性与继承属性
- Object.prototype.isPrototypeOf
- 语法
- 示例
- Object.prototype.prototypeIsEnumerable
- 语法
- 示例
- 基本示例
- 自有属性与继承属性
- Object.prototype.toString
- 语法
- 描述
- 示例
- 基本示例
- 检测对象类型
- Object.isExtensible
- 语法
- 描述
- 示例
- Function
- 语法
- Function.prototype.apply
- 语法
- 描述
- 示例
- 数组元素添加
- 内置函数使用
- Function.prototype.call
- 语法
- 示例
- Function.prototype.bind
- 语法
- 描述
- 示例
- 创建绑定函数
- 偏函数
- 配合定时器
- String
- 语法
- 说明
- 模板字面量
- String.fromCharCode
- 语法
- 使用示例
- String.prototype.charAt()
- 语法
- 说明
- 示例
- String.prototype.charCodeAt()
- 语法
- 说明
- 示例
- String.prototype.concat()
- 语法
- 说明
- 示例
- String.prototype.endsWith()
- 语法
- 说明
- 示例
- String.prototype.includes()
- 语法
- 示例
- String.prototype.indexOf()
- 语法
- 示例
- 区分大小写
- 统计字符串中字母数量
- 检测字符是否存在
- String.prototype.match()
- 语法
- 说明
- 示例
- 全局模式和不区分大小写模式
- 不传参数
- 判断是否是微信浏览器
- String.prototype.replace()
- 语法
- 描述
- 示例
- 代码示例
- String.prototype.slice()
- 语法
- 描述
- 示例
- 代码示例
- String.prototype.split()
- 语法
- 描述
- 示例
- 代码示例
- String.prototype.toLowerCase()
- 语法
- 描述
- 示例
- String.prototype.toUpperCase()
- 语法
- 描述
- 示例
- Array 对象
- 语法
- Array.from()
- 语法
- 方法说明
- 代码示例
- 基本用法
- Array.isArray()
- 语法
- 代码示例
- Array.prototype.concat()
- 语法
- 方法说明
- 代码示例
- 连接两个数组
- Array.prototype.indexOf()
- 语法
- 方法说明
- 代码示例
- 基本用法
- Array.prototype.join()
- 语法
- 方法说明
- 代码示例
- 基本用法
- Array.prototype.flat()
- 语法
- 代码示例
- 基本用法
- Array.prototype.every()
- 语法
- 方法说明
- 代码示例
- Array.prototype.filter()
- 语法
- 方法说明
- 代码示例
- 基本用法
- Array.prototype.find()
- 语法
- 代码示例
- 用对象的属性查找数组里的对象
- Array.prototype.findIndex()
- 语法
- 代码示例
- 基本用法
- Array.prototype.forEach()
- 语法
- 方法说明
- 代码示例
- Array.prototype.map()
- 语法
- 方法说明
- 代码示例
- Array.prototype.push()
- 语法
- 方法说明
- 代码示例
- 基本用法
- Array.prototype.pop()
- 语法
- 方法说明
- 代码示例
- 基本用法
- Array.prototype.sort()
- 语法
- 方法说明
- 代码示例
- 基本用法
- 总结
全局对象
值属性
Infinity
全局属性 Infinity
是一个数值,表示无穷大。
Infinity
属性的属性特性
属性特性 | 布尔值 |
---|---|
writable | false |
enumerable | false |
configurable | false |
说明
Infinity
是全局对象的一个属性,即它是一个全局变量。Infinity
的初始值是Number.POSITIVE_INFINITY
。
Infinity
大于任何值。该值和数学意义上的无穷大很像,例如任何正值乘以 Infinity
为 Infinity
,任何数值(除了 Infinity
和 -Infinity
)除以 Infinity
为 0。
示例
🌰 代码示例:
console.log(Infinity);
// Infinity
console.log(Infinity + 1);
// Infinity
console.log(Math.pow(10, 1000));
// Infinity
console.log(Math.log(0));
// Infinity
console.log(1 / Infinity);
// 0
NaN
全局属性 NaN
的值表示不是一个数字(Not-A-Number)。
属性特性 | 布尔值 |
---|---|
writable | false |
enumerable | false |
configurable | false |
说明
NaN
是一个全局对象的属性。NaN
属性的初始值就是NaN
,和Number.NaN
的值一样。- 编码中很少直接使用到
NaN
。通常都是在计算失败时,作为Math
的某个方法的返回值出现的(例如:Math.sqrt(-1)
)或者尝试将一个字符串解析成数字但失败了的时候(例如:parseInt('blabla')
)。
返回 NaN
的情况总结:
- 无穷大除以无穷大
- 给任意负数做开放运算
- 算术运算符与不是数字或无法转换为数字的操作数一起使用
- 字符串解析为数字
示例
值校验
不可使用等号运算符来判断一个值是否为 NaN
。必须采用 Number.isNaN()
或 isNaN()
函数进行判断。
在执行自比较中,NaN
是唯一与自身不全等的值。
NaN === NaN;
// false
Number.NaN === NaN;
// false
isNaN(NaN);
// true;
isNaN(Number.NaN);
// true;
function valueIsNaN(v) {
return v !== v;
}
valueIsNaN(1);
// false
valueIsNaN(NaN);
// true
valueIsNaN(Number.NaN);
// true
使用 isNaN()
前先检查一下这个值是否是数字类型,即可避免隐式类型转换的问题。
function detectIsNaN(value) {
return typeof value === 'number' && isNaN(value);
}
undefined
undefined
属性是一个特殊值。如果已声明了一个变量但还未进行初始化,则其值为 undefined
。
该属性为 Global
对象的一个只读属性(准确地说,是一个常量)。所有主流浏览器均支持该属性。
说明
如果一个变量未被初始化赋值,则其值为 undefined
。如果一个函数没有返回值,则其返回值默认为 undefined
。
函数属性
eval
eval()
函数用于计算并执行以字符串表示的 JavaScript 代码。eval()
函数使 JavaScript 可以动态执行 JavaScript 源代码。
eval()
函数属于 Global
对象,所有主流浏览器均支持该函数。
语法
eval(code);
参数 | 类型 | 说明 |
---|---|---|
code | String 类型 | 包含有效 JavaScript 代码的字符串 |
⚠️ 注意: 参数code
必须是原始字符串,不能是 String 对象形式。如果参数 code
不是原始字符串,则 eval()
函数不会执行代码,并且将其不作任何改变地返回。
如果参数 code
中的 JavaScript 代码不合法,将会引发异常。
eval()
函数的返回值是任意类型,其返回值由参数 code
中具体的 JavaScript 代码决定。
说明
- 传递给
eval()
函数的代码执行时所在的上下文和调用eval()
函数时的上下文一样(也就是说,作用域不变)。 - 请自行确认
code
代码的来源是可信的,否则使用eval()
函数存在一定的安全隐患。
示例
let x = 2,
y = 39,
z = '42';
eval('x + y + 1');
// 42
eval(z);
// 42
isNaN
isNaN()
函数用于判断指定数字是否是非数字值 NaN
。
该函数属于Global
对象,所有主流浏览器均支持该函数。
语法
isNaN(number);
参数 | 类型 | 说明 |
---|---|---|
number | Number 类型 | 指定的数值 |
⚠️ 注意: 如果参数 number
不是 Number 类型,则 isNaN()
函数会将其强制转换为 Number 类型再进行判断。大多数其他类型的值无法强制转换为 Number 类型,则其转换结果为 NaN
,即 isNaN()
函数返回 true
。
-
isNaN()
函数的返回值是 Boolean 类型。
- 如果指定的数字为
NaN
,则返回true
- 如果指定的数字为非
NaN
则返回false
。
- 如果指定的数字为
说明
- 通常使用此函数检测来自
parseInt()
和parseFloat()
函数的返回值。 - 将某些不能强制转换为数字类型的值的非数字类型的值转换为数字类型的值时,也会得到
NaN
。 NaN
不能通过相等操作符来判断,因为NaN
是唯一一个与其自身不等的值。
示例
isNaN(NaN);
// true
isNaN(undefined);
// true
isNaN({});
// true
isNaN(true);
// false
isNaN(null);
// false
isNaN(37);
// false
// strings
isNaN('37');
// false: 可以被转换成数值37
isNaN('37.37');
// false: 可以被转换成数值37.37
isNaN('');
// false: 空字符串被转换成0
isNaN(' ');
// false: 包含空格的字符串被转换成0
// dates
isNaN(new Date());
// false
isNaN(new Date().toString());
// true
isNaN('blabla');
// true: "blabla"不能转换成数值
parseFloat
parseFloat()
函数用于将字符串转换为浮点数并返回。
该函数属于 Global
对象,所有主流浏览器均支持该函数。
语法
parseFloat(numberString);
参数 | 类型 | 说明 |
---|---|---|
numberString | String 类型 | 需要转换为浮点数的字符串。 |
-
返回转换后的浮点数,
number
类型,
- 如果指定的字符串中包含非数字字符,只要字符串开头的一部分符合浮点数规则,则
parseFloat()
函数会将这一部分字符串转化为数字(从字符串开头,直到遇到非数字字符为止)。 - 如果字符串以非数字字符开头,则返回
NaN
。
- 如果指定的字符串中包含非数字字符,只要字符串开头的一部分符合浮点数规则,则
示例
- 返回正常数字
parseFloat('3.14');
parseFloat('314e-2');
parseFloat('0.0314E+2');
parseFloat('3.14more non-digit characters');
// all return 3.14
- 返回
NaN
parseFloat('MDN');
// NaN
parseFloat(null);
// NaN
parseFloat([]);
// NaN
parseFloat({});
// NaN
parseInt
parseInt()
函数用于 将字符串转换为整数并返回。该函数可以将字符串视作指定的进制形式表示。
该函数属于 Global
对象,所有主流浏览器均支持该函数。
语法
parseInt( numString [, radix ] )
参数 | 类型 | 说明 |
---|---|---|
numString | String 类型 | 需要转换为整数的字符串 |
radix | Number 类型 | 可选,指定的进制基数(介于 [2, 36] 之间的数值。) |
例如:参数 radix
为 2,则将 numString
视作二进制;参数 radix
为 8,则视作八进制;参数 radix
为 16,则视作十六进制。
如果没有提供 radix
参数,则 parseInt()
函数将会根据参数 numString
的前缀来决定转换的进制基数。如果 numString
的前缀是 0x
,则转换为十六进制;如果前缀是 0
,则转换为八进制;其他情况均转换为十进制。
parseInt()
函数的返回值为 Number 类型,返回转换后的整数- 如果指定的字符串中包含非数字字符,只要字符串开头的一部分符合整数的转换规则,则
parseInt()
函数会将这一部分字符串转化为整数(从字符串开头,直到遇到非数字字符为止)。 - 如果字符串以非数字字符开头,则返回
NaN
。
- 如果指定的字符串中包含非数字字符,只要字符串开头的一部分符合整数的转换规则,则
示例
- 正常使用
parseInt()
,以下均返回 15
// Binary
parseInt('1111', 2);
// Octal
parseInt('17', 8);
parseInt(021, 8);
// Decimal
parseInt('015', 10);
parseInt(15.99, 10);
parseInt('15,123', 10);
parseInt('15 * 3', 10);
parseInt('15e2', 10);
parseInt('15px', 10);
parseInt('12', 13);
// Hexadecimal
parseInt('0xF', 16);
parseInt('F', 16);
parseInt('FXX123', 16);
- 以下均返回
NaN
parseInt('Hello', 8);
// not a number
parseInt('546', 2);
// except 0 & 1,other number are not valid binary numbers
decodeURI
decodeURI()
函数用于对已编码的统一资源标识符(URI)进行解码,并返回其非编码形式。
该函数属于 Global
对象,所有主流浏览器均支持该函数。
语法
decodeURI(encodedURIString);
参数 | 类型 | 说明 |
---|---|---|
encodedURIString | String 类型 | 已编码的 URI 字符串 |
decodeURI()
函数的返回值是 string
类型,返回一个已经解码的 URI。
将已编码 URI 中所有能识别的转义序列转换成原字符,但不能解码那些不会被 encodeURI
编码的内容(例如 #
)。
示例
let a = 'Hello JavaScript!';
let b = encodeURI(a);
console.log(b);
// return '%E4%BD%A0%E5%A5%BDJavascript!'
let c = decodeURI(b);
// return '你好Javascript!'
encodeURI
encodeURI()
函数可把 URI 字符串采用 UTF-8 编码格式转化成 escape 格式的字符串。
该函数属于 Global
对象,所有主流浏览器均支持该函数。
语法
encodeURI(URIString);
参数 | 类型 | 说明 |
---|---|---|
URIString | String 类型 | 需要编码的 URI 字符串 |
该方法返回一个已经编码的 URI 字符串。
说明
如果要对使用 encodeURI()
函数编码的 URI 字符串进行解码,请使用 decodeURI()
函数。
encodeURI()
函数不编码字符有 82 个 !
、#
、$
、'
、(
、)
、*
、+
、,
、-
、.
、/
、:
、;
、=
、?
、@
、_
、~
、0-9
、a-z
、A-Z
。
如果你只是想编码一个带有特殊字符(比如中文)的 URI,这个 URI 用作请求地址,请使用本函数。
如果你想把 URI 当作请求参数传递,那么你可以使用 encodeURIComponent()
函数。encodeURIComponent()
函数会编码所有的字符。
示例
// 原URI
var ftpUri = 'ftp://192.168.0.100/共享文件夹';
// 编码URI
var encodedFtpUri = encodeURI(ftpUri);
console.log(encodedFtpUri); // ftp://192.168.0.100/%E5%85%B1%E4%BA%AB%E6%96%87%E4%BB%B6%E5%A4%B9
// 解码URI
var decodedFtpUri = decodeURI(encodedFtpUri);
console.log(decodedFtpUri); // ftp://192.168.0.100/共享文件夹
Object
JavaScript 中的 Object
对象,是 JavaScript 中所有对象的基类,也就是说 JavaScript 中的所有对象都是由 Object 对象衍生的。Object 对象主要用于将任意数据封装成对象形式。
对象也可看做是属性的无序集合,每个属性都是一个名值对。属性名是字符串,因此我们可以把对象看成是从字符串到值的映射。
语法
构造函数
new Object([value]);
对象类型转换函数
Object([value]);
参数 | 说明 | 类型 |
---|---|---|
value | 可选参数,需要包装为对象的值 | any |
Object.assign
Object.assign()
方法用于将所有可枚举自有 Property 的值从一个或多个源对象拷贝到目标对象。
语法
Object.assign(target, ...sources);
参数 | 说明 | 类型 |
---|---|---|
target | 目标对象 | object |
sources | 源对象 | object |
返回目标对象。
描述
如果目标对象中的属性具有相同的键,则属性将被源对象中的属性覆盖。后面的源对象的属性将类似地覆盖前面的源对象的属性。
Object.assign
方法只会拷贝源对象自身的并且可枚举的属性到目标对象。
该方法使用源对象的 [[Get]]
和目标对象的 [[Set]]
,所以它会调用相关 getter
和 setter
。因此,它分配属性,而不仅仅是复制或定义新的属性。如果合并源包含 getter
,这可能使其不适合将新属性合并到原型中。为了将属性定义(包括其可枚举性)复制到原型,应使用 Object.getOwnPropertyDescriptor
和 Object.defineProperty
。
示例
基本示例
const a = { a: 1 };
const b = Object.assign({}, a);
console.log(b); // { a: 1 }
Object.create
Object.create()
方法用于创建指定对象为原型对象的新对象。
语法
语法:
Object.create(o: object | null): any;
Object.create(o: object | null, properties: PropertyDescriptorMap & ThisType<any>): any;
类型声明拓展:
interface PropertyDescriptor {
configurable?: boolean;
enumerable?: boolean;
value?: any;
writable?: boolean;
get?(): any;
set?(v: any): void;
}
interface PropertyDescriptorMap {
[s: string]: PropertyDescriptor;
}
interface ThisType<T> {}
参数说明:
参数 | 说明 | 类型 |
---|---|---|
o | 新创建对象指向的原型对象 | object |
properties | 可选参数。添加到新创建对象的可枚举属性(即自身定义的属性,而不是原型链上的枚举属性) | object |
⚠️ 注意:
- 如果
properties
参数不是null
或对象,则抛出一个 TypeError 异常 - 返回指定原型对象和可枚举属性的新对象
示例
类式继承
// Shape = Super Class
function Shape() {
this.x = 0;
this.y = 0;
}
// Super Class Methods
Shape.prototype.move = function () {
this.x += x;
this.y += y;
console.log('Shap moved');
};
// Retangle - Sub Class
function Retangle() {
Shape.all(this); // call super constructor
}
// 子类继承父类
Retangle.prototype = Object.create(Shape.prototype);
Retangle.prototype.constructor = Retangle;
const rect = new Retangle();
console.log(rect instanceof Retangle);
// true
console.log(rect instanceof Shape);
// true
Object.defineProperties
Object.defineProperties()
方法用于为一个对象定义 Properties 和/或修改已有的 Properties 的 Attributes。
语法
Object.defineProperties(O, Properties);
参数 | 说明 | 类型 |
---|---|---|
O | 添加或修改 Properties 的目标对象 | object |
Properties | 要定义其可枚举属性或修改的属性描述符的对象 | object |
Attributes | 默认值 |
---|---|
configurable | false |
enumerable | false |
value | undefined |
writable | false |
get | undefined |
set | undefined |
返回变更后的对象。
示例
const abc = { a: 1, b: 2, c: 3 };
Object.defineProperties(abc, {
a: {
value: 'One',
writable: false,
enumerable: false,
configurable: false,
},
e: {
value: 4,
},
f: {
value: 5,
},
});
console.log(abc);
// {
// b: "Two",
// c: 3,
// a: "One",
// d: "Three",
// e: 4,
// f: 5,
// }
abc.a = 10;
console.log(abc.a);
// 'One'
Object.defineProperty
Object.defineProperty()
方法用于为一个对象定义一个自有 Property 和/或修改已有 Property 的 Attributes。
语法
Object.defineProperty(O, P, Attributes);
参数 | 说明 | 类型 |
---|---|---|
O | 定义或修改 Property 的目标对象 | object |
P | 需要定义的 Property 键名 | string |
Attributes | 被定义或修改的 Attributes | object |
返回变更后的对象。
示例
const foo = {};
Object.defineProperty(foo, 'a', {
value: 100,
writable: true,
enumerable: true,
configurable: true
})
console.log(foo);
// { a: 100 }
const bar;
// 添加属性和存取描述符
Object.defineProperty(foo, 'b', {
get: function(){
return foo
},
set: function(newValue){
bar = newValue
},
enumerable: true,
configurable: true,
})
foo.b = 99;
console.log(foo.b);
// 99
对象属性劫持
遍历劫持对象的所有属性
const data = {
a: 'a',
b: 'b',
c: 'c'
};
// 遍历对象,对其属性值进行劫持
Object.keys(data).forEach(function(key) {
Object.defineProperty(data, key, {
enumerable: true,
configurable: true,
get: function() {
console.log('GET')
},
set: function(value) {
// 当属性值发生变化时我们可以进行额外操作
console.log('SET')
}
})
})
Object.entries
⭐️ ES2017(ES8)新特性
Object.entries()
方法用于枚举指定对象并返回以键值对组成的数组为元素的二维数组。
语法
语法:
Object.entries(obj);
类型声明:
interface ObjectConstructor {
values<T>(o: { [s: string]: T } | ArrayLike<T>): T[];
values(o: {}): any[];
}
参数说明:
参数 | 说明 | 类型 |
---|---|---|
obj | 用于枚举的对象 | object |
返回值:
返回给定对象自身可枚举 Property 的键值对数组。
方法说明
给定对象自身可枚举属性的键值对数组,其排列与使用 for-in
循环遍历该对象时返回的顺序一致,区别在于 for-in
循环也枚举原型链中的属性。
代码示例
const a = { foo: 1, bar: 2 };
Object.entries(a);
// [['foo', 1], ['bar', 2]]
Object.entries('foo');
// [ ['0', 'f'], ['1', 'o'], ['2', 'o'] ]
const obj = { a: 5, b: 7, c: 9 };
for (const [key, value] of Object.entries(obj)) {
console.log(`${key} ${value}`);
// "a 5", "b 7", "c 9"
}
Object.entries(obj).forEach(([key, value]) => {
console.log(`${key} ${value}`); // "a 5", "b 7", "c 9"
});
Object.entries
⭐️ ES2017(ES8)新特性
Object.entries()
方法用于枚举指定对象并返回以键值对组成的数组为元素的二维数组。
语法
语法:
Object.entries(obj);
类型声明:
interface ObjectConstructor {
values<T>(o: { [s: string]: T } | ArrayLike<T>): T[];
values(o: {}): any[];
}
参数说明:
参数 | 说明 | 类型 |
---|---|---|
obj | 用于枚举的对象 | object |
返回值:
返回给定对象自身可枚举 Property 的键值对数组。
方法说明
给定对象自身可枚举属性的键值对数组,其排列与使用 for-in
循环遍历该对象时返回的顺序一致,区别在于 for-in
循环也枚举原型链中的属性。
代码示例
const a = { foo: 1, bar: 2 };
Object.entries(a);
// [['foo', 1], ['bar', 2]]
Object.entries('foo');
// [ ['0', 'f'], ['1', 'o'], ['2', 'o'] ]
const obj = { a: 5, b: 7, c: 9 };
for (const [key, value] of Object.entries(obj)) {
console.log(`${key} ${value}`);
// "a 5", "b 7", "c 9"
}
Object.entries(obj).forEach(([key, value]) => {
console.log(`${key} ${value}`); // "a 5", "b 7", "c 9"
});
Object.getOwnPropertyDescriptor
Object.getOwnPropertyDescriptor()
方法可以获取对象自有 Property 的某个 Attributes。
语法
Object.getOwnPropertyDescriptor(O, Property);
参数 | 说明 | 类型 |
---|---|---|
O | 需要查找的目标对象 | object |
Property | 目标对象的 Property | string |
示例
const foo = { a: 1 };
Object.getOwnPropertyDescriptor(foo, 'a');
// Object {
// value: "a",
// writable: true,
// enumerable: true,
// configurable: true,
// }
Object.getOwnPropertyDescriptors
⭐️ ES2017(ES8)新特性
Object.getOwnPropertyDescriptors()
方法用于获取一个对象的所有自身 Property 的 Attributes。
语法
语法:
Object.getOwnPropertyDescriptors(obj);
类型声明:
interface ObjectConstructor {
getOwnPropertyDescriptors<T>(
o: T
): { [P in keyof T]: TypedPropertyDescriptor<T[P]> } & { [x: string]: PropertyDescriptor };
}
interface TypedPropertyDescriptor<T> {
enumerable?: boolean;
configurable?: boolean;
writable?: boolean;
value?: T;
get?: () => T;
set?: (value: T) => void;
}
interface PropertyDescriptor {
configurable?: boolean;
enumerable?: boolean;
value?: any;
writable?: boolean;
get?(): any;
set?(v: any): void;
}
参数说明:
参数 | 说明 | 类型 |
---|---|---|
obj | 用于获取 Property 的 Attributes 的对象 | object |
代码示例
const a = {
name: 'Ben',
get age() {
return '18';
},
};
Object.getOwnPropertyDescriptors(a);
Object.getPrototypeOf
Object.getPrototypeOf()
方法用于获取指定对象的原型(内部 [[Prototype]]
属性的值)。
语法
Object.getPrototypeOf(O);
参数 | 说明 | 类型 |
---|---|---|
O | 目标对象 | object |
返回目标对象的原型对象。
示例
基本示例
const proto = {};
const foo = Object.create(proto);
Object.getPrototypeOf(foo) === proto;
// true
const reg = /a/;
Object.getPrototypeOf(reg) === Regexp.prototype;
// true
标准内置对象
const foo = new Object();
Object.getPropertyOf(Object);
// f () { [native code] }
Object.getPropertyOf(Function);
// f () { [native code] }
Object.getPropertyOf(Object) === Function.prototype;
// true
const bar = new Object();
Object.prototype === Object.getPrototypeOf(bar);
// true
Obejct.prototype === Object.getPrototypeOf({});
// true
Object.is
Object.is()
方法用于判断两个值是否是相同的值。
语法
Object.is(value1, value2);
参数 | 说明 | 类型 |
---|---|---|
value1 | 比较值 1 | any |
value2 | 比较值 2 | any |
返回判断表达式的结果。
描述
判断下列任何一项成立,则两个值相同:
- 两个值均为
undefined
- 两个值均为
null
- 两个值都是
true
或false
- 两个值是由相同个数的字符按照相同顺序组成的字符串
- 两个值指向同一个对象
- 两个值都是数字并且
- 都是正零
+0
- 都是负零
-0
- 都是
NaN
- 都是除零和
NaN
外的其他同一个数字
- 都是正零
这种相等性判断逻辑和传统的 ==
运算不同,==
运算符会对它两边的操作数做隐式类型转换,然后才进行相等性比较,(所以才会有类似 "" == false
等于 true
的现象),但 Object.is
不会做这种类型转换。
这与 ===
运算符的判定方式也不一样。===
运算符(和 ==
运算符)将数字值 -0
和 +0
视为相等,并认为 Number.NaN
不等于 NaN
。
示例
Object.is(undefined, undefined);
// true
Object.is(null, null);
// true
Object.is(true, true);
// true
Object.is(100, 100);
// true
Object.is('foo', 'bar');
// false
Object.is([], []);
// false
Object.is(0, -0);
// false
Object.is(-0, -0);
// true
Object.is(NaN, 0 / 0);
// true
Object.keys
Object.keys()
方法用于获取指定对象自身可枚举 Property 组成的键名数组。
语法
Object.keys(O);
参数 | 说明 | 类型 |
---|---|---|
O | 指定对象 | object |
返回对象所有可枚举 Property 的键名组成的数组。
描述
获取到的数组中键名顺序与使用 for
系列循环语句获取到的键名顺序一致。
示例
数组
const foo = ['a', 'b', 'c'];
console.log(Object.keys(foo));
// console: ['0', '1', '2']
类数组
const foo = { 0: 'a', 1: 'b', 2: 'c' };
console.log(Object.keys(foo));
// console: ['0', '1', '2']
不可枚举属性
// getBar is a property which isn't enumerable
const foo = Object.create(
{},
{
getBar: {
value: function() {
return this.bar;
},
},
}
);
foo.bar = 1;
console.log(Object.keys(foo));
// ['bar']
Object.setPrototypeOf
Object.setPrototypeOf()
方法用于设置一个指定的对象的原型 ( 即,内部 [[Prototype]]
属性)到另一个对象或 null
。
语法
Object.setPrototypeOf(O, proto);
参数 | 说明 | 类型 |
---|---|---|
O | 要设置其原型的对象 | object |
proto | 原型对象 | object |
返回设置原型后的对象。
示例
const foo = Object.setPrototypeOf({}, null);
代码实现
if (!Object.setPrototypeOf) {
Object.setPrototypeOf = function() {};
}
Object.values
⭐️ ES2017(ES8)新特性
Object.values()
方法用于指定对象自身的所有可枚举 Property 值的数组。
语法
语法:
Object.values(obj);
类型声明:
interface ObjectConstructor {
values<T>(o: { [s: string]: T } | ArrayLike<T>): T[];
values(o: {}): any[];
}
参数说明:
参数 | 说明 | 类型 |
---|---|---|
obj | 指定对象 | object |
返回对象可枚举 Property 值的数组集合。
方法说明
返回的数组中键值的顺序与使用循环语句获取的键值组合一致。
代码示例
const obj = {
a: '1',
b: '2',
c: '3',
};
console.log(Object.values(obj));
// ['1', '2', '3']
Object.prototype.hasOwnProperty
Object.prototype.hasOwnProperty
方法用于检测指定对象自有 Properties 中是否具有指定的 Property。
语法
O.prototype.hasOwnProperty(V);
参数 | 说明 | 类型 |
---|---|---|
V | 需要检测的 Property 字符串名称或者 Symbol | string/symbol |
返回该对象是否含有指定 Property 的 Boolean 值。
描述
所有继承了 Object 的对象都会继承到 hasOwnProperty
方法。
这个方法可以用来检测一个对象是否含有特定的自身属性;和 in
运算符不同,该方法会忽略掉那些从原型链上继承到的属性。
示例
基本示例
const foo = new Object();
foo.a = 'exist';
function change() {
foo.b = foo.a;
delete foo.a;
}
foo.hasOwnProperty('a');
// true
change();
foo.hasOwnProperty('b');
// false
自有属性与继承属性
const foo = new Object();
foo.a = 'Hello world!';
foo.hasOwnProperty('a');
// true
foo.hasOwnProperty('toString');
// false
foo.hasOwnProperty('hasOwnProperty');
// false
Object.prototype.isPrototypeOf
Object.prototype.isPrototypeOf()
方法用于测试指定对象是否存在于目标对象的原型链上。
语法
O.prototype.isPrototypeOf(V);
参数 | 说明 | 类型 |
---|---|---|
V | 目标对象(在该对象原型链上搜寻) | object |
返回指定对象是否位于目标对象原型链上的 Boolean 类型值。
示例
function Foo() {}
function Bar() {}
function Baz() {}
Bar.prototype = Object.create(Foo.prototype);
Baz.prototype = Object.create(Bar.prototype);
const baz = new Baz();
console.log(Baz.prototype.isPrototypeOf(baz));
// true
console.log(Bar.prototype.isPrototypeOf(baz));
// true
console.log(Foo.prototype.isPrototypeOf(baz));
// true
console.log(Object.prototype.isPrototypeOf(baz));
// true
Object.prototype.prototypeIsEnumerable
Object.prototype.prototypeIsEnumerable()
方法用于检测指定 Property 是否可枚举。
语法
O.prototype.prototypeIsEnumerable(V);
参数 | 说明 | 类型 |
---|---|---|
V | 需要检测的 Property 键名 | string |
返回表示指定 Property 键名是否可枚举的 Boolean 类型值。
示例
基本示例
const foo = {};
const bar = [];
foo.a = 'is enumerable';
bar[0] = 'is enumerable';
foo.propertyIsEnumerable('a');
// true
bar.propertyIsEnumerable(0);
// true
自有属性与继承属性
原型链上 的 Properties 不被 propertyIsEnumerable
考虑。
const a = [];
a.propertyIsEnumerable('constructor');
function b() {
this.property = 'b';
}
b.prototype.firstMethod = function() {};
function c() {
this.method = function method() {
return 'c';
};
}
c.prototype = new b();
c.prototype.constructor = c;
const d = new c();
d.arbitraryProperty = 'd';
d.prototypeIsEnumerable('arbitraryProperty');
// true
d.prototypeIsEnumerable('method');
// true
d.prototypeIsEnumerable('property');
// false
d.property = 'd';
d.prototypeIsEnumerable('property');
// true
Object.prototype.toString
Object.prototype.toString()
方法用于表示指定对象的字符串。
语法
O.prototype.toString();
表示该对象的字符串。
描述
所有经过标准内置对象创建的值均能通过 toString()
方法获取 String 类型值。
示例
基本示例
const foo = new Object();
foo.toString();
// [object Object]
检测对象类型
需要使用 Function.prototype.call()
和 Function.prototype.apply()
的形式调用,输入需要检测的对象作为第一参数。
const toString = Object.prototype.toString();
toString.call(new Date());
// [object Date]
toString.call(new String());
// [object String]
toString.call(Math);
// [object Math]
// Since JavaScript 1.8.5
toString.call(undefined);
// [object Undefined]
toString.call(null);
// [object Null]
Object.isExtensible
Object.isExtensible()
方法用于检测指定对象是否可扩展。
语法
Object.isExtensible(O);
参数 | 说明 | 类型 |
---|---|---|
O | 指定用于检测的对象 | object |
返回 Boolean 类型的值表示用于检测的对象是否可扩展。
描述
默认情况下,对象是可扩展的:即可以为他们添加新的属性。
Object.preventExtensions
、Object.seal
或 Object.freeze
方法都可以标记一个对象为不可扩展(non-extensible)。
示例
let foo = {
a: 1,
};
console.log(Object.isExtensible(foo));
// true
foo.b = 2;
console.log(foo);
// {a: 1, b: 2}
console.log(Object.preventExtensions(foo));
// { a: 1, b: 2}
// 由于对象 foo 禁止扩展,所以该赋值语句静默失败
foo.c = 3;
console.log(Object.isExtensible(foo));
// false
console.log(foo);
// { a: 1, b: 2}
Function
Function 构造函数通过 new
创建一个新的 Function 对象。 在 JavaScript 中,每个函数实际上都是一个 Function 对象。
语法
构造函数
new Function ( [ argName1 [, argName1 [, argNameN... [, funcBody ]]]] )
函数类型转换函数
Function ( [ argName1 [, argName1 [, argNameN... [, funcBody ]]]] )
参数 | 说明 | 类型 |
---|---|---|
argName1 | 定义的第 1 个参数的名称 | string |
argName2 | 定义的第 2 个参数的名称 | string |
argNameN | 定义的第 N 个参数的名称,可以有任意多个 | string |
funcBody | 定义的函数主体,即函数内部的执行代码,默认为空字符串("" ) | string |
Function()
会把传入的最后一个参数作为函数定义的执行代码,之前的所有参数均依次作为函数定义的参数。
- 如果没有指定任何参数,则表示该函数没有定义参数列表,函数的执行代码也为空。
- 如果只指定了一个参数,则该参数将被视作函数的执行代码。如果你想定义一个参数、执行代码为空,请传入两个参数,第二个参数为空字符串即可:
new Function("argName1", "")
。
Function()
的返回值是 Function 类型,返回一个函数对象。
Function.prototype.apply
Function.prototype.apply
方法用于指定函数调用指向的 this
指针,并提供类数组类型的参数列表作为指定函数的参数。
语法
语法:
apply(thisArg: any, argArray?: any): any;
参数:
参数 | 说明 | 类型 |
---|---|---|
thisArg | 可选参数。调用函数时指向的 this 指针。 | / |
argArray | 可选参数。调用函数参数列表。 | Array | TypedArray |
描述
Function.prototype.apply
与 Function.prototype.call
非常相似,不同之处在于提供参数的方式,apply
使用参数数组而非一组参数列表。
你可以使用 arguments
对象作为 argArray
参数。arguments
是一个函数的局部变量,它可以被用作被调用对象的所有未指定的参数。这样,你在使用 apply
方法时就不需要知道被调用的对象的所有参数。你可以使用 arguments
来把所有的参数传递给被调用对象。 被调用对象接下来就负责处理这些参数。
示例
数组元素添加
使用 Array.prototype.push
能将元素追加到数组中,并且,该方法可以接受可变数量的参数。
但是如果,我们需要传递一个数组追加到数组中,它实际上会将该数组作为单个元素添加,而不是单独添加元素,因此我们最终得到一个数组内的数组。
这种情况下,虽然可以通过 Array.prototype.concat
实现我们想要的行为,但它实际上不是附加到原有数组中,而是创建并返回新的数组。
而我们可以通过 Function.prototype.apply
实现该需求。
const foo = [];
const bar = [1, 2, 3, 4];
foo.push.apply(foo, bar);
console.log(foo);
// [1, 2, 3, 4]
内置函数使用
可以使用 Function.prototype.apply
实现本来需要遍历数组变量的任务中使用内建的的函数。
以下例子使用 Math.max
和 Math.min
来找出一个数组中的最大 / 最小值。
const foo = [2, 4, 6, 8, 10];
const max = Math.max.apply(null, foo);
const min = Math.min.apply(null, foo);
⚠️ 注意:使用上述方式调用 Function.prototype.apply
,会有超出 JavaScript 引擎的参数长度限制的风险。当对一个函数传入非常多的参数(比如一万个)时,就非常有可能会导致越界问题,这个临界值是根据不同的 JavaScript 引擎而定的(JavaScript 核心中已经做了硬编码 参数个数限制在 65536),因为这个限制(实际上也是任何用到超大栈空间的行为的自然表现)是未指定的,有些引擎会抛出异常。更糟糕的是其他引擎会直接限制传入到方法的参数个数,导致参数丢失。
如果参数数组可能很大,可以使用以下策略处理:将参数数组切块后循环传入目标方法。
function minOfArray(arr) {
var min = Infinity;
var QUANTUM = 32768;
for (var i = 0, len = arr.length; i < len; i += QUANTUM) {
var submin = Math.min.apply(null, arr.slice(i, Math.min(i + QUANTUM, len)));
min = Math.min(submin, min);
}
return min;
}
var min = minOfArray([5, 6, 2, 3, 7]);
Function.prototype.call
Function.prototype.call
方法用于指定函数调用指向的 this
指针,并分别提供参数作为指定函数的参数。
语法
语法:
call(thisArg: any, ...argArray: any[]): any;
参数
参数 | 说明 | 类型 |
---|---|---|
thisArg | 可选参数。调用函数时指向的 this 指针。 | |
args | 可选参数。调用函数参数列表。 |
示例
function Product(name, price) {
this.name = name;
this.price = price;
}
function Food(name, price) {
Product.call(this, name, price);
this.category = 'food';
}
function Toy(name, price) {
Product.call(this, name, price);
this.category = 'toy';
}
const cheese = new Food('cheese', 5);
const robot = new Toy('robot', 40);
console.log(cheese);
// {
// category: "food",
// name: "cheese",
// price: 5,
// }
console.log(robot);
// {
// category: "toy",
// name: "robot",
// price: 40,
// }
Function.prototype.bind
Function.prototype.bind
方法创建一个新函数,在 bind()
被调用时,这个新函数的 this
被指定为 bind()
的第一个参数,而其余参数将作为新函数的参数,供调用时使用。
语法
语法:
bind(thisArg: any, ...argArray: any[]): any;
参数
参数 | 说明 | 类型 |
---|---|---|
thisArg | 可选参数。调用函数时指向的 this 指针。 | / |
arg1,arg2,… | 可选参数。当目标函数被调用时,被预置入绑定函数的参数列表中的参数。 | any |
描述
Function.prototype.bind
函数会创建一个新 绑定函数(Bound Function,BF)。绑定函数是一个 Exotic Function Object(怪异函数对象,ECMAScript 2015 中的术语),它包装了原函数对象。调用绑定函数通常会导致执行 包装函数。
绑定函数具有以下内部属性:
[[BoundTargetFunction]]
:包装的函数对象[[BoundThis]]
:在调用包装函数时始终作为this
值传递的值。[[BoundArguments]]
:列表,在对包装函数做任何调用都会优先用列表元素填充参数列表。[[Call]]
:执行与此对象关联的代码。通过函数调用表达式调用。内部方法的参数是一个this
值和一个包含通过调用表达式传递给函数的参数的列表。
当调用绑定函数时,它调用 [[BoundTargetFunction]]
上的内部方法 [[Call]]
,就像这样 Call(boundThis, args)
。其中,boundThis
是 [[BoundThis]]
,args
是 [[BoundArguments]]
加上通过函数调用传入的参数列表。
绑定函数也可以使用 new
运算符构造,它会表现为目标函数已经被构建完毕。提供的 this
值会被忽略,但前置参数仍会提供给模拟函数。
示例
创建绑定函数
Function.prototype.bind()
最简单的用法是创建一个函数,不论怎么调用,这个函数都有同样的 this
引用。JavaScript 新手经常犯的一个错误是将一个方法从对象中拿出来,然后再调用,期望方法中的 this
是原来的对象(比如在回调中传入这个方法)。如果不做特殊处理的话,一般会丢失原来的对象。基于这个函数,用原始的对象创建一个绑定函数,巧妙地解决了这个问题。
this.a = '100';
const foo = {
a: '99',
getA: function () {
return this.a;
},
};
foo.getA();
// '99'
const retrieveA = foo.getA;
retrieveA();
// '100'
const boundGetA = retrieveA.bind(foo);
boundGetA();
// '99'
偏函数
Function.prototype.bind()
方法的另一个最简单的用法是使一个函数拥有预设的初始参数。只要将这些参数(如果有的话)作为 bind()
的参数写在 this
后面。当绑定函数被调用时,这些参数会被插入到目标函数的参数列表的开始位置,传递给绑定函数的参数会跟在它们后面。
const foo = function (a, b, c, d, e, f) {
console.log(a, b, c, d, e, f);
};
// 预设三个参数 1 2 3 -> 对应 foo 参数 a b c
const bar = foo.bind(null, 1, 2, 3);
bar(4, 5, 6);
// 1 2 3 4 5 6
配合定时器
默认情况下,使用 window.setTimeout 时,this
关键字会指向 Window 对象。当类的方法中需要 this
指向类的实例时,你可能需要显式地把 this
绑定到回调函数,就不会丢失该实例的引用。
function LaterBloomer() {
this.petalCount = Math.ceil(Math.random() * 12) + 1;
}
LaterBloomer.prototype.bloom = function () {
window.setTimeout(this.declare.bind(this), 1000);
};
LateBloomer.prototype.declare = function () {
console.log('I am a beautiful flower with ' + this.petalCount + ' petals!');
};
const flower = new LateBloomer();
flower.bloom();
String
String 对象是一个用于 字符串 或一个 字符序列 的构造函数。
String 对象是文本字符串的对象形式。String 对象允许操作和格式化文本字符串以及确定和定位字符串中的子字符串。
语法
构造函数
new String([value]);
字符串类型转换函数
String([value]);
参数 | 类型 | 说明 |
---|---|---|
value | 任意类型 | 任何可以被转换成字符串的值。 |
说明
模板字面量
从 ECMAScript 2015 开始,字符串字面量也可以称为 模板字面量:
const w = 'world'`Hello ${w}!`;
String.fromCharCode
静态 String.fromCharCode()
方法返回由指定的 UTF-16 代码单元序列创建的字符串。
语法
String.fromCharCode(num1 [, num2 [, num3 ...[, numN]]]);
参数:
num
:一系列 UTF-16 代码单元的数字。范围介于 0 到 65535(0xFFFF
)之间。大于0xFFFF
的数字将被截断。不进行有效性检查。
使用示例
String.fromCharCode(65, 66, 67);
// ABC
String.fromCharCode(0x2014);
// -
String.prototype.charAt()
charAt()
方法从一个字符串中返回指定的字符。
语法
str.charAt(index);
参数 | 说明 | 类型 |
---|---|---|
index | 一个介于 0 和字符串长度减 1 之间的整数。 (0~length-1)。如果没有提供索引,默认值为 0。 | number |
说明
字符串中的字符从左向右索引:
- 第一个字符的索引值为 0
- 最后一个字符(假设该字符位于字符串
stringName
中)的索引值为stringName.length - 1
- 如果指定的
index
值超出了该范围,则返回一个空字符串''
示例
const javascript = 'JAVASCRIPT';
javascript.charAt();
// J
javascript.charAt(0);
// J
javascript.charAt(1);
// A
javascript.charAt(2);
// V
javascript.charAt(3);
// A
javascript.charAt(4);
// S
javascript.charAt(5);
// C
javascript.charAt(6);
// R
javascript.charAt(7);
// I
javascript.charAt(8);
// P
javascript.charAt(9);
// T
javascript.charAt(100);
// ''
String.prototype.charCodeAt()
charCodeAt()
方法返回 0 到 65535 之间的整数,表示给定索引处的 UTF-16 代码单元(在 Unicode 编码单元表示一个单一的 UTF-16 编码单元的情况下,UTF-16 编码单元匹配 Unicode 编码单元。但在——例如 Unicode 编码单元 > 0x10000
的这种——不能被一个 UTF-16 编码单元单独表示的情况下,只能匹配 Unicode 代理对的第一个编码单元) 。如果你想要整个代码点的值,使用 codePointAt()
。
语法
str.charCodeAt(index);
参数 | 说明 | 类型 |
---|---|---|
index | 一个大于等于 0,小于字符串长度的整数。如果不是一个数值,则默认为 0。 | number |
返回值表示字符串对象指定索引处的字符的 Unicode 编码;如果索引超出范围,则返回 NaN
。
说明
Unicode 编码单元(code points)的范围从 0 到 1114111(0x10FFFF
)。开头的 128 个 Unicode 编码单元和 ASCII 字符编码一样。
⚠️ 注意,charCodeAt
总是返回一个小于 65536 的值。这是因为高位编码单元(higher code point)使用一对(低位编码(lower valued))代理伪字符(“surrogate” pseudo-characters)来表示,从而构成一个真正的字符。因此,为了查看或复制(reproduce)65536 及以上编码字符的完整字符,需要在获取 charCodeAt(i)
的值的同时获取 charCodeAt(i+1)
的值,或者改为获取 codePointAt(i)
的值。
如果指定的 index
小于 0 或不小于字符串的长度,则 charCodeAt
返回 NaN
。
示例
下例介绍了不同索引情况下返回的 Unicode 值:
'ABC'.charCodeAt(0);
// 65
'ABC'.charCodeAt(1);
// 66
'ABC'.charCodeAt(2);
// 67
'ABC'.charCodeAt(3);
// NaN
String.prototype.concat()
concat()
函数用于将当前字符串与指定字符串进行拼接,并返回拼接后的字符串。
语法
str.concat( string2, string3 [, ..., stringN] )
参数 | 说明 | 类型 |
---|---|---|
str2...strN | 和原字符串连接的多个字符串。 | string |
concat()
函数的返回值为 String
类型,其返回值为拼接后的字符串。
concat()
函数的作用等同于运算符 +
,例如:str.concat(str1, str2)
等同于 str + str1 + str2
。
说明
concat
方法将一个或多个字符串与原字符串连接合并,形成一个新的字符串并返回。 concat
方法并不影响原字符串。
示例
下面的例子演示如何将多个字符串与原字符串合并为一个新字符串
var hello = 'Hello, ';
hello.concat('Kevin', ' have a nice day.');
// Hello, Kevin have a nice day.
建议使用赋值操作符(+
或 +=
)代替字符串的 concat
方法。
var hello = 'Hello, ';
hello += 'world';
console.log(hello);
// Hello, world
String.prototype.endsWith()
endsWith()
用来判断当前字符串是否是以另外一个给定的子字符串 结尾
的,根据判断结果返回 true
或 false
。
语法
str.endsWith( searchString [, length] )
参数 | 说明 | 类型 |
---|---|---|
searchString | 要搜索的子字符串 | string |
length | 作为 str 的长度 | number |
这个方法帮助你确定一个字符串是否在另一个字符串的末尾。这个方法是大小写敏感的。
说明
concat
方法将一个或多个字符串与原字符串连接合并,形成一个新的字符串并返回。 concat
方法并不影响原字符串。
示例
const str = 'Hello world!';
console.log(str.endsWith('world!'));
// true
console.log(str.endsWith('abc'));
// false
String.prototype.includes()
includes()
方法用于判断一个字符串是否包含在另一个字符串中,根据情况返回 true
或 false
。
语法
str.includes( searchString [, startIndex] )
参数 | 说明 | 类型 |
---|---|---|
searchString | 要在字符串中搜索的字符串 | string |
startIndex | 从当前字符串指定索引位置开发搜索子字符串,默认为 0,包含该索引 | number |
这个方法可以帮你判断一个字符串是否包含另外一个字符串。
这个方法搜索匹配的字符串是区分大小写的。
示例
var str = 'To be, or not to be, that is the question.';
console.log(str.includes('To be'));
// true
console.log(str.includes('question'));
// true
console.log(str.includes('nonexistent'));
// false
console.log(str.includes('To be', 1));
// false
console.log(str.includes('TO BE'));
// false
String.prototype.indexOf()
indexOf()
函数用于查找子字符串在当前字符串中第一次出现的位置。
语法
str.indexOf( searchValue[, startIndex])
参数 | 说明 | 类型 |
---|---|---|
searchValue | 需要查找的子字符串。 | string |
startIndex | 可选,在当前字符串中查找的起始索引,默认为 0。 | number |
indexOf()
方法的返回值为 Number 类型,返回子字符串在当前字符串中第一次查找到的起始位置(索引)。
示例
字符串中的字符被从左向右索引。首字符的索引(index)为 0,字符串 stringName
的最后一个字符的索引是 stringName.length - 1
。
'Blue Whale'.indexOf('Blue');
// 0
'Blue Whale'.indexOf('Blute');
// -1
'Blue Whale'.indexOf('Whale', 0);
// 5
'Blue Whale'.indexOf('Whale', 5);
// 5
'Blue Whale'.indexOf('', 9);
// 9
'Blue Whale'.indexOf('', 10);
// 10
'Blue Whale'.indexOf('', 11);
// 10
区分大小写
下例定义了两个字符串变量。
两个变量包含相同的字符串,除了第二个字符串中的某些字符为大写。第一个 log
方法输出 19。但是由于 indexOf
方法 区分大小写,因此不会在 myCapString
中发现字符串 “cheddar"
,结果第二个 log
方法输出 -1。
var myString = 'brie, pepper jack, cheddar';
var myCapString = 'Brie, Pepper Jack, Cheddar';
console.log('myString.indexOf("cheddar") is ' + myString.indexOf('cheddar'));
// 19
console.log('myCapString.indexOf("cheddar") is ' + myCapString.indexOf('cheddar'));
// -1
统计字符串中字母数量
使用 indexOf
统计一个字符串中某个字母出现的次数
在下例中,设置了 count
来记录字母 e 在字符串 str
中出现的次数:
let str = 'To be, or not to be, that is the question.';
let count = 0;
let cur = str.indexOf('e');
// 当 cur 为 -1 时表示,字符串中已无检索子字符串
while (cur !== -1) {
count++;
cur = str.indexOf('e', cur + 1);
}
console.log(count); // displays 4
检测字符是否存在
当检测某个字符串是否存在于另一个字符串中时,可使用下面的方法:
'Blue Whale'.indexOf('Blue') !== -1;
// true
'Blue Whale'.indexOf('Bloe') !== -1;
// false
String.prototype.match()
match()
函数用于使用指定的正则表达式模式在当前字符串中进行匹配查找,并返回数组形式的查找结果。
语法
str.match(regexp);
参数 | 说明 | 类型 |
---|---|---|
regexp | 包含正则表达式模式的 RegExp 对象的实例。也可以是包含正则表达式模式的变量名或字符串。 | RegExo |
💡 如果参数 regExp
不是正则表达式对象(RegExp),而是字符串类型,则 match()
先将该字符串传递给 RegExp 的构造函数,将其转换为一个 RegExp 对象。
match()
方法的返回值为 Array 类型,其返回数组的成员取决于指定的正则表达式模式是否设有全局标志 g
。
- 如果参数
regExp
没有全局标志g
,则match()
函数只查找第一个匹配,并返回包含查找结果的数组,该数组对象包含如下成员:- 索引
0
:存放第一个匹配的子字符串。 - 属性
index
:匹配文本在字符串中的起始索引位置。 - 属性
input
:整个字符串对象(str
)。
- 索引
在 IE 6 ~ IE 8 中,该数组还具有额外的 lastIndex
属性,用于存储匹配文本最后一个字符的下一个位置。
-
如果参数
regExp
设有全局标志g
,则match()
函数会查找所有的匹配,返回的数组不再有index
和input
属性,其中的数组元素就是所有匹配到的子字符串,形如:- 索引
0
:存放第一个匹配的子字符串(如果存在的话)。 - 索引
1
:存放第二个匹配的子字符串(如果存在的话)。 - ……
- 索引
N-1
:存放第 N 个匹配的字符串(如果存在的话)。
- 索引
-
match()
函数如果没有查找到任何匹配,则返回null
。
说明
- 如果你需要知道一个字符串是否匹配一个正则表达式 RegExp ,可使用
String.prototype.search()
。 - 如果你只是需要第一个匹配结果,你可能想要使用
RegExp.prototype.exec()
。 - 如果你想要获得捕获组,并且设置了全局标志,你需要用
RegExp.prototype.exec()
。
示例
在下例中,使用 match 查找 "Hello world!"
紧跟着 1 个或多个数值字符,再紧跟着一个小数点和数值字符 0 次或多次。正则表达式包含 i
标志,因此大小写会被忽略。
var str = 'Hello world!';
str.match();
// ["", index: 0, input: "Hello world!", groups: undefined]
str.match(/\b\w/);
// ["H", "w"]
str.match(/\w(?=r)/g);
// null
str.match(/\w[^\w]/g);
// ["o", "d!"]
全局模式和不区分大小写模式
下例展示了 match()
使用 global
和 ignore case
标志。A-E
、a-e
的所有字母将会作为一个数组的元素返回。
var str = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
var regexp = /[A-E]/gi;
var matchArray = str.match(regexp);
console.log(matchArray);
// ['A', 'B', 'C', 'D', 'E', 'a', 'b', 'c', 'd', 'e']
不传参数
var str = 'Nothing will come of nothing.';
str.match();
// [""]
判断是否是微信浏览器
const isWeixin = function() {
const ua = naviagtor.userAgent.toLowerCase();
if (ua.match(/MicroMessenger/i) === 'micromessenger') {
return true
} else {
return false;
}
}
String.prototype.replace()
replace()
函数用于使用指定字符串替换当前字符串中匹配指定正则表达式模式的子字符串,并返回完成替换后的字符串。
语法
str.replace(pattern, replacement);
参数 | 说明 | 类型 |
---|---|---|
pattern | 指定的正则表达式模式的 RegExp 对象的实例。也可以是字符串。 | string / RegExp |
replacement | 用于替换的字符串,或返回替换字符串的函数。 | string / function |
一个部分或全部匹配由替代模式所取代的新的字符串。
描述
- 如果参数
pattern
是字符串,则replace()
函数将直接根据该字符串进行精确匹配,而不会试图转换为正则表达式,并且 只替换第一个匹配到 的子字符串 - 参数
replacement
可以使用以下以$
开头的 匹配变量 来动态确定用于替换的字符串内容(参数pattern
为正则表达式时才生效)
字符 | 描述 |
---|---|
$n | 假如第一个参数是 RegExp 对象,并且 n 是个小于 100 的非负整数,那么插入第 n 个括号匹配的字符串。 |
$& | 插入匹配的子串。 |
`$`` | 插入当前匹配的子串左边的内容。 |
$' | 插入当前匹配的子串右边的内容。 |
$$ | 插入一个 $ 。 |
在进行全局的搜索替换时,正则表达式需包含 g
标志。
- 指定一个函数作为参数
你可以指定一个函数作为第二个参数。在这种情况下,当匹配执行后, 该函数就会执行。 函数的返回值作为替换字符串。(注意: 上面提到的特殊替换参数在这里不能被使用。) 另外要注意的是, 如果第一个参数是正则表达式, 并且其为全局匹配模式, 那么这个方法将被多次调用, 每次匹配都会被调用。
下面是该函数的参数:
变量名 | 代表的值 |
---|---|
match | 匹配的子串。(对应于上述的 \$& 。) |
p1,p2, … | 假如 replace() 方法的第一个参数是一个 RegExp 对象,则代表第 n 个括号匹配的字符串。(对应于上述的 $1 ,$2 等。) |
offset | 匹配到的子字符串在原字符串中的偏移量。(比如,如果原字符串是 'abcd' ,匹配到的子字符串是 'bc' ,那么这个参数将是 1) |
string | 被匹配的原字符串。 |
精确的参数个数依赖于 replace()
的第一个参数是否是一个正则表达式对象, 以及这个正则表达式中指定了多少个括号子串。
示例
代码示例
在下面的例子中,replace()
中使用了正则表达式及忽略大小写标示。
var str = 'Twas the night before Xmas...';
var newstr = str.replace(/xmas/i, 'Christmas');
console.log(newstr);
// Twas the night before Christmas...
var str = 'Hello world!';
// 将字符 'lo' 替换为 '**'
str.replace('lo', '**');
// "Hel** world!"
// 将所有 'h' 替换为 '**'(全局,忽略大小写)
str.replace(/h/ig);
// '**ello world!'
// 将位于单词边界前的两个字母替换为 '**'
str.replace(/\w{2}\b/g, '**');
// "Hel** wor**!"
// 将位于起始位置与单词边界的两个字母替换为 '**'(没有匹配项)
str.replace(/^\w{2}\b/g/, '**');
// "Hello world!"
// 在所有的连续两个字母并且后面不跟字母 'l' 的字母前添加 "**"
// 这里的 "$1" 就表示正则表达式中第一个小括号内的子表达式匹配到的内容
str.replace(/(\w{2}(?!l))/g, '**$1');
// "He**llo **wo**rld!"
String.prototype.slice()
slice()
方法提取字符串的某部分,并返回一个新的字符串。
语法
str.slice( startIndex [, endIndex] )
参数 | 说明 | 类型 |
---|---|---|
startIndex | 指向字符串指定部分的开头的索引。 | number |
endIndex | 可选,指向字符串指定部分的结尾的索引(不包括该索引),默认到字符串的结尾。 | number |
返回一个从原字符串中提取出来的新字符串
描述
slice()
函数一直从索引 startIndex
复制到 endIndex
所指示的字符,但是不包括 endIndex
索引上的字符。
- 如果
startIndex
为负,则将其视为str.length + startIndex
。 - 如果省略
endIndex
,则将一直提取到字符串的结尾。 - 如果
endIndex
为负,则将其视为str.length + endIndex
。 - 如果
endIndex
小于等于startIndex
,则不会复制任何字符,返回空字符串。
示例
代码示例
var str = 'abcdefghij';
// 开始索引省略即从 0 开始提取,结束索引省略即提取到字符串末尾
str.slice(); // 'abcdefghij'
// 开始索引为 0,结束索引省略即提取到字符串末尾
str.slice(0);
// 'abcdefghij'
// 开始索引为 0,结束索引为2
str.slice(0, 2);
// 'ab'
// 开始索引为 -3 即负数,即为 -3+10=7,结束索引省略即提取到字符串末尾
str.slice(-3);
// 'hij'
// 开始索引为 0,结束索引为 -3 即 -3+10=7
str.slice(0, -3);
// 'abcdef'
// 开始索引为 -3 即 -3+10=7,结束索引为 -1+10=9
str.slice(-3, -1);
String.prototype.split()
split()
函数用于使用指定分隔符分割字符串,并返回分割后的若干个子字符串组成的数组。
语法
str.split( [separator [, limit]] )
参数 | 说明 | 类型 |
---|---|---|
separator | 指定表示每个拆分应发生的点的字符串。separator 可以是一个字符串或正则表达式。 如果纯文本分隔符包含多个字符,则必须找到整个字符串来表示分割点。如果在 str 中省略或不出现分隔符,则返回的数组包含一个由整个字符串组成的元素。如果分隔符为空字符串,则将 str 原字符串中每个字符的数组形式返回。 | string / RegExp |
limit | 可选,一个整数,限定返回的分割片段数量。当提供此参数时,split 方法会在指定分隔符的每次出现时分割该字符串,但在限制条目已放入数组时停止。如果在达到指定限制之前达到字符串的末尾,它可能仍然包含少于限制的条目。新数组中不返回剩下的文本。 | number |
-
找到分隔符后,将其从字符串中删除,并将子字符串的数组返回。
-
如果没有找到或者省略了分隔符,则该数组包含一个由整个字符串组成的元素。
-
如果分隔符为空字符串,则字符串会在每个字符之间分割。
-
如果分隔符出现在字符串的开始或结尾,或两者都分开,分别以空字符串开头,结尾或两者开始和结束。因此,如果字符串仅由一个分隔符实例组成,则该数组由两个空字符串组成。
-
如果分隔符是包含捕获括号的正则表达式,则每次分隔符匹配时,捕获括号的结果(包括任何未定义的结果)将被拼接到输出数组中。但是,并不是所有浏览器都支持此功能。
-
当被查找的字符串为空时,返回一个包含一个空字符串的数组,而不是一个空数组,如果字符串和分隔符都是空字符串,则返回一个空数组。
描述
如果提供了 limit
参数,此函数返回的数组最多包含 limit
个元素。如果参数 limit
为负数,则该参数将被忽略掉。如果省略了 limit
,则 split()
函数不会考虑长度,直到分割完毕为止。如果 limit
为 0,则返回空的数组。
示例
代码示例
'abcd'.split();
// ["abcd"]
'abcd'.split('b');
// ["a", "cd"]
'abcd'.split('a');
// ["", "bcd"]
'abcd'.split('d');
// ["abc", ""]
'abcd'.split('abcd');
// ["", ""]
'abcd'.split('');
// ["a", "b", "c", "d"]
'abcd'.split(' ');
// ["abcd"]
''.split();
// [""]
''.split('');
// []
''.split(' ');
// [""]
String.prototype.toLowerCase()
toLowerCase()
函数用于将当前字符串的所有字母转为小写,并返回转换后的字符串。该函数基于常规的 Unicode 大小写映射进行转换。
语法
str.toLowerCase();
描述
toLowerCase
将调用该方法的字符串值转换为小写形式,并返回。toLowerCase()
方法不影响字符串本身的值,返回的是新的字符串。
示例
var abc = 'ABC';
abc.toLowerCase();
// 'abc'
String.prototype.toUpperCase()
toUpperCase()
函数用于将当前字符串中的所有字母转为大写,并返回转换后的字符串。该函数基于常规的 Unicode 大小写映射进行转换。
语法
str.toUpperCase();
描述
toUpperCase
将调用该方法的字符串值转换为大写形式,并返回。toUpperCase
方法不影响字符串本身的值,返回的是新的字符串。
示例
var abc = 'abc';
abc.toUpperCase();
// 'ABC'
Array 对象
Array
对象时用于构造数组的全局对象,类似时类似于列表的高阶对象。
Array
对象主要用于存储多个数据项,数据可以是任意类型。
所有主流浏览器均支持该对象。
语法
字面量
[element0, element1, ..., elementN]
数组类型转换函数
Array(element0, element1, ..., elementN)
构造函数
new Array(element0, element1, ..., elementN)
new Array(arrayLength)
Array.from()
⭐️ ES2015(ES6)新特性
Array.from()
方法用于将一个类数组对象或可迭代对象转换成一个新的数组实例。
语法
语法:
Array.from(arrayLike [, mapfn [, thisArg]])
类型声明:
interface ArrayLike<T> {
readonly length: number;
readonly [n: number]: T;
}
interface ArrayConstructor {
from<T>(arrayLike: ArrayLike<T>): T[];
from<T, U>(arrayLike: ArrayLike<T>, mapfn: (v: T, k: number) => U, thisArg?: any): U[];
}
参数说明:
参数 | 说明 | 类型 |
---|---|---|
arrayLike | 想要转换成数组的伪数组对象或可迭代对象 | typed array |
mapfn | (可选)如果指定了该参数,新数组中的每个元素会执行该回调函数。 | function |
thisArg | (可选)执行回调函数 mapFn 时 this 对象 | object |
返回值:
返回一个新的数组实例。
方法说明
-
具备以下两种条件的的对象可以通过
Array.from()
方法转换成真正的数组:
- 类数组对象:即拥有
length
属性和若干索引属性的任意对象 - 可迭代对象:即部署了 Iterator 接口的对象,可以获取对象中的元素,如
Map
和Set
等
- 类数组对象:即拥有
-
Array.from()
方法有一个可选参数mapfn
,让你可以在最后生成的数组上再执行一次Array.prototype.map
方法后再返回。也就是说Array.from(arrayLike, mapfn, thisArg)
就相当于Array.from(arrayLike).map(mapfn, thisArg)
,除非创建的不是可用的中间数组。 这对一些数组的子类,如对类型化数组来说很重要,因为中间数组的值在调用map()
时需要是适当的类型。 -
from()
的length
属性为 1 ,即Array.from.length === 1
。 -
在 ES2015 中,
Class
语法允许我们为内置类型(比如Array
)和自定义类新建子类(比如叫SubArray
)。这些子类也会继承父类的静态方法,比如SubArray.from()
,调用该方法后会返回子类SubArray
的一个实例,而不是Array
的实例。
代码示例
基本用法
const bar = ['a', 'b', 'c'];
Array.from(bar); // ["a", "b", "c"]
Array.from('foo'); // ["f", "o", "o"]
Array.isArray()
Array.isArray()
方法用于确定某个值是否是数组类型。
语法
语法:
Array.isArray(arg);
类型声明:
interface ArrayConstructor {
isArray(arg: any): arg is any[];
}
declare var Array: ArrayConstructor;
参数说明:
参数 | 说明 | 类型 |
---|---|---|
arg | 需要检测的值 | any |
返回值:
如果对象是 Array
的实例,则返回 true
;否则为 false
。
代码示例
下面的函数调用都返回 true
Array.isArray([]);
Array.isArray([1]);
Array.isArray(new Array());
Array.isArray(Array.prototype);
鲜为人知的事实:其实 Array.prototype
也是一个数组。
Array.isArray(Array.prototype);
下面的函数调用都返回 false
。
Array.isArray();
Array.isArray({});
Array.isArray(null);
Array.isArray(undefined);
Array.isArray(17);
Array.isArray('Array');
Array.isArray(true);
Array.isArray(false);
Array.isArray({ __proto__: Array.prototype });
Array.prototype.concat()
Array.prototype.concat()
方法用于合并两个或多个数组。此方法不会更改现有数组,而是返回一个新数组。
语法
语法:
const new_array = old_array.concat( item1[, itemN ] )
类型声明:
interface ConcatArray<T> {
readonly length: number;
readonly [n: number]: T;
join(separator?: string): string;
slice(start?: number, end?: number): T[];
}
interface Array<T> {
concat(...items: ConcatArray<T>[]): T[];
concat(...items: (T | ConcatArray<T>)[]): T[];
}
参数说明:
参数 | 描述 | 类型 |
---|---|---|
item1 | 添加到当前数组末尾处的数据项 | any |
itemN | 要添加到当前数组末尾处的其他项,可以有多个。 | any |
返回值:
返回合并后新的 Array
实例。
方法说明
concat
方法创建一个新的数组,它由被调用的对象中的元素组成,每个参数的顺序依次是该参数的元素(如果参数是数组)或参数本身(如果参数不是数组)。它不会递归到嵌套数组参数中。
concat
方法不会改变 this
或任何作为参数提供的数组,而是返回一个浅拷贝,它包含与原始数组相结合的相同元素的副本。 原始数组的元素将复制到新数组中,如下所示:
- 对象引用(而不是实际对象):
concat
将对象引用复制到新数组中。原始数组和新数组都引用相同的对象。 也就是说,如果引用的对象被修改,则更改对于新数组和原始数组都是可见的。这包括也是数组的数组参数的元素。 - 数据类型如字符串,数字和布尔(不是
String
,Number
和Boolean
对象):concat
将字符串和数字的值复制到新数组中。
注意:数组/值在连接时保持不变。此外,对于新数组的任何操作(仅当元素不是对象引用时)都不会对原始数组产生影响,反之亦然。
代码示例
连接两个数组
以下代码将两个数组合并为一个新数组。
const alpha = ['a', 'b', 'c'];
const numeric = [1, 2, 3];
alpha.concat(numeric);
// Outputs: ['a', 'b', 'c', 1, 2, 3]
Array.prototype.indexOf()
Array.prototype.indexOf()
方法用于查找数组成员第一次出现指定字符的位置。
语法
语法:
arr.indexOf( searchElement [, fromIndex] )
类型声明:
interface Array<T> {
indexOf(searchElement: T, fromIndex?: number): number;
}
参数说明:
参数 | 说明 | 类型 |
---|---|---|
searchElement | 要查找的数组元素 | any |
fromIndex | 可选,在当前字符串中查找的起始索引,默认为 0 | number |
返回值:
返回数组元素在当前数组中第一次查找到的起始位置(索引)
方法说明
该方法使用 Strict Equality(无论是绝对相等 ===
,还是 Triple-equals 操作符都基于同样的方法)进行判断查找的元素与数组中包含的元素之间的关系。
代码示例
基本用法
var arr = [1, 2, 3, 4, 5];
arr.indexOf(1);
// 0
arr.indexOf(7);
// -1
arr.indexOf(4, 2);
// 3
arr.indexOf(3, -1);
// -1
arr.indexOf(3, -3);
// 2
Array.prototype.join()
Array.prototype.join()
方法将数组(或类数组对象)的所有成员连接到字符串中。
语法
语法:
const str = arr.jon(separator);
类型声明:
interface Array<T> {
join(separator?: string): string;
}
参数说明:
参数 | 说明 | 类型 |
---|---|---|
separator | 将数组各元素连接成字符串的字符 | string |
返回值:
返回一个所有数组成员连接的字符串。如果数组长度为 0,则返回空字符串。
方法说明
所有的数组成员被转换成字符串,再用一个分隔符将这些字符串连接起来。如果元素是 undefined
或者 null
, 则会转化成空字符串。
代码示例
基本用法
const arr = ['1', '2', '3', '4', '5'];
// 不传参数默认以逗号作为分隔符
arr.join();
// '1,2,3,4,5'
arr.join(', ');
// '1, 2, 3, 4, 5'
arr.join(' + ');
// '1 + 2 + 3 + 4 + 5'
arr.join('');
// '12345'
Array.prototype.flat()
⭐️ ES2019(ES10)新特性
Array.prototype.flat()
方法会按照一个可指定的深度递归遍历数组,并将所有元素与遍历到的子数组中的元素合并为一个新数组返回。
语法
语法:
arr.flat([depth]);
类型声明:
type FlatArray<Arr, Depth extends number> = {
done: Arr;
recur: Arr extends ReadonlyArray<infer InnerArr>
? FlatArray<
InnerArr,
[-1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20][Depth]
>
: Arr;
}[Depth extends -1 ? 'done' : 'recur'];
interface ReadonlyArray<T> {
flat<A, D extends number = 1>(this: A, depth?: D): FlatArray<A, D>[];
}
interface Array<T> {
flat<A, D extends number = 1>(this: A, depth?: D): FlatArray<A, D>[];
}
参数说明:
参数 | 说明 | 类型 |
---|---|---|
depth | (可选参数)指定要提取嵌套数组的结构深度,默认值为 1 | number |
返回值:
返回一个包含将数组与子数组种所有元素的新数组。
代码示例
基本用法
const arr1 = [0, 1, 2, [3, 4]];
console.log(arr1.flat());
// exprected output: [0, 1, 2, 3, 4]
const arr2 = [0, 1, 2, [[[3, 4]]]];
console.log(arr2.flat());
// exprected output: [0, 1, 2, [ 3, 4]];
Array.prototype.every()
every()
方法遍历数组中每个成员,通过回调函数判断是否所有成员都满足特定条件。
语法
语法:
arr.every( predicate [, thisArg ] )
类型声明:
interface Array<T> {
every<S extends T>(
predicate: (value: T, index: number, array: T[]) => value is S,
thisArg?: any
): this is S[];
every(predicate: (value: T, index: number, array: T[]) => unknown, thisArg?: any): boolean;
}
参数说明:
参数 | 说明 | 类型 |
---|---|---|
predicate | 用于判定数组成员的回调函数 | function |
thisArg | 执行回调函数的 this 值 |
callback
函数的参数:
currentValue
:当前数组中处理的元素index
:数组中正处理的当前元素的索引array
:被调用的数组
返回值:
返回当所有数组元素满足回调函数的判断时返回 true
,否则返回 false
。
方法说明
- 执行该方法会为数组每个成员执行一次回调函数,回调函数需要通过判断代码块后,返回布尔值作为该成员是否通过检测的凭证,如果通过则再为下一个数组成员执行回调函数,直到遇到第一个判断为
false
的数组成员则立即给实例方法返回false
,否则全部成员都通过检测的回调函数,则返回true
。 - 回调函数只会为那些已经被赋值的索引调用,不会为那些被删除或从来没有被赋值的索引调用。
- 如果为实例方法提供一个
thisArg
参数,则该参数为调用回调函数时的this
值。如果省略该参数,则为回调函数被调用时的this
值,在非严格模式下为全局对象,在严格模式下传入undefined
。 - 遍历的数组成员范围在第一次调用回调函数之前就已确定了。在调用
every()
之后添加到数组中的成员不会被回调函数访问到。如果数组中存在的成员被更改,则他们传入回调函数的值是every()
访问到他们那一刻的值。那些被删除的成员或未被赋值的成员将不会被访问到。
代码示例
下例检测数组中的所有元素是否都大于 10。
const isBigEnough = (element, index, array) =>
(element >= 10)[(12, 5, 8, 130, 44)].every(isBigEnough)[
// false
(12, 54, 18, 130, 44)
].every(isBigEnough);
// true
Array.prototype.filter()
Array.prototype.filter()
方法创建一个新数组,其包含通过所提供函数实现的测试的所有元素。
语法
语法:
arr.filter( callback = function (currentValue, index, arr) {} [, thisArg ] )
类型声明:
interface Array<T> {
filter<S extends T>(
predicate: (value: T, index: number, array: T[]) => value is S,
thisArg?: any
): S[];
filter(predicate: (value: T, index: number, array: T[]) => unknown, thisArg?: any): T[];
}
参数说明:
参数 | 说明 | 类型 |
---|---|---|
callback | 用于判定数组成员的回调函数 | function |
thisArg | 执行回调函数的 this 值 |
callback
函数的参数:
currentValue
:当前数组中处理的元素index
:数组中正处理的当前元素的索引array
:被调用的数组
返回值:
返回一个新的通过测试的成员的集合的数组。
方法说明
- 该方法为数组中的每个成员调用一次回调函数,并利用所有使得回调函数返回
true
或 等价于true
的值的成员创建一个新数组。回调函数只会在已经赋值的索引上被调用,对于那些已经被删除或者从未被赋值的索引不会被调用。那些没有通过回调函数测试的元素会被跳过,不会被包含在新数组中。 - 如果提供
thisArg
参数,则它会被作为回调函数被调用时的this
值。否则,回调函数的this
值在非严格模式下将是全局对象,严格模式下为undefined
。 - 遍历的元素范围在第一次调用回调函数之前就已经确定了。在调用该方法之后被添加到数组中的元素不会被 遍历到。如果已经存在的元素被改变了,则他们传入回调函数的值是遍历到它们那一刻的值。被删除或从来未被赋值的元素不会被遍历到。
代码示例
基本用法
const isBigEnough = (value) => value >= (10)[(12, 5, 8, 130, 44)].filter(isBigEnough);
// false
Array.prototype.find()
Array.prototype.find()
方法返回数组中满足提供的判定函数的第一个成员。
语法
语法:
arr.find( callback [, thisArg ] )
类型声明:
interface Array<T> {
find<S extends T>(
predicate: (this: void, value: T, index: number, obj: T[]) => value is S,
thisArg?: any
): S | undefined;
find(predicate: (value: T, index: number, obj: T[]) => unknown, thisArg?: any): T | undefined;
}
参数说明:
参数 | 说明 | 类型 |
---|---|---|
callback | 用于判定数组成员的回调函数 | function |
thisArg | 执行回调函数的 this 值 |
callback
函数的参数:
currentValue
:当前数组中处理的元素index
:数组中正处理的当前元素的索引array
:被调用的数组
返回值:
当遍历到的数组成员通过回调函数的判定时,返回数组中该成员,否则返回 undefined
。
代码示例
用对象的属性查找数组里的对象
let foo = [
{ name: 'a', quantity: 2 },
{ name: 'b', quantity: 0 },
{ name: 'c', quantity: 5 },
];
const getFoo = (key) => (arr) => arr.name === key;
console.log(foo.find(getFoo('c')));
// { name: 'c', quantity: 5 }
Array.prototype.findIndex()
findIndex()
方法返回数组中满足提供的测试函数的第一个元素的索引。否则返回-1。
语法
语法:
arr.findIndex( callback [, thisArg ])
类型声明:
interface Array<T> {
findIndex(predicate: (value: T, index: number, obj: T[]) => unknown, thisArg?: any): number;
}
参数说明:
参数 | 类型 | 说明 |
---|---|---|
callback | 用于判定数组成员的回调函数 | function |
thisArg | 执行回调函数的 this 值 |
callback
函数的参数:
currentValue
:当前数组中处理的元素index
:数组中正处理的当前元素的索引array
:被调用的数组
代码示例
基本用法
const arr = [1, 2, 3, 4, 5, 12, 22, 2, 2, 2];
const foo = arr.findIndex(function (currentValue, index, array) {
return currentValue === 2;
});
console.log(foo);
// 1
Array.prototype.forEach()
Array.prototype.forEach()
方法用于迭代数组的每项成员。
语法
语法:
arr.forEach( callbackfn [, thisArg ] )
类型声明:
interface Array<T> {
forEach(callbackfn: (value: T, index: number, array: T[]) => void, thisArg?: any): void;
}
参数说明:
参数 | 说明 | 类型 |
---|---|---|
callbackfn | 用于遍历数组成员时执行的回调函数 | function |
thisArg | 执行回调函数的 this 值 |
callbackfn
函数的参数:
currentValue
:当前数组中处理的元素index
:数组中正处理的当前元素的索引array
:被调用的数组
返回值:
返回 undefined
。
方法说明
- 该方法按升序为数组中含有效值的每一项执行一次回调函数,那些已删除(使用
delete
方法等情况)或者未初始化的项将被跳过(但不包括那些值为undefined
的项,例如在稀疏数组中)。 - 该方法遍历的范围在第一次调用回调函数前就会确定。调用
forEach()
后添加到数组中的项不会被callbackfn
访问到。如果已经存在的值被改变,则传递给callbackfn
的值是forEach
遍历到他们那一刻的值。已删除的项不会被遍历到。如果已访问的元素在迭代时被删除了(例如使用shift()
) ,之后的元素将被跳过。 forEach()
为每个数组元素执行callbackfn
函数;不像map()
或者reduce()
,它总是返回undefined
值,并且不可链式调用。典型用例是在一个链的最后执行副作用。
注意: 没有办法中止或者跳出 forEach
循环,除了抛出一个异常。如果你需要这样,使用 forEach()
函数是错误的,你可以用一个简单的循环作为替代。如果您正在测试一个数组里的元素是否符合某条件,且需要返回一个布尔值,那么可使用 every()
或 some()
。如果可用,新方法 find()
或者 findIndex()
也可被用于真值测试的提早终止。
代码示例
const arr = ['a', 'b', 'c'];
arr.forEach(function (element) {
console.log(element);
});
arr.forEach((element) => console.log(element));
// a b c
Array.prototype.map()
Array.prototype.map()
根据传递的转换函数,更新给定数组中的每个值,并返回一个相同长度的新数组。它接受一个回调函数作为参数,用以执行转换过程。
语法
语法:
const new_arr = old_arr.map(callback = function(currentValue, index, array){} [, thisArg])
类型声明:
interface Array<T> {
map<U>(callbackfn: (value: T, index: number, array: T[]) => U, thisArg?: any): U[];
}
参数说明:
参数 | 说明 | 类型 |
---|---|---|
callbackFunc | 用于遍历数组成员时执行的回调函数 | function |
thisArg | 执行回调函数的 this 值 |
callback
函数的参数:
currentValue
:当前数组中处理的元素index
:数组中正处理的当前元素的索引array
:被调用的数组
返回值:
返回回调函数的结果,如果未设定返回值,则返回当前遍历的数组成员。
方法说明
- 该方法按升序为数组中含有效值的每一项执行一次回调函数,那些已删除(使用
delete
方法等情况)或者未初始化的项将被跳过(但不包括那些值为undefined
的项,例如在稀疏数组中)。 - 使用
map
方法处理数组时,数组元素的范围是在callback
方法第一次调用之前就已经确定了。在map
方法执行的过程中:原数组中新增加的元素将不会被callback
访问到;若已经存在的元素被改变或删除了,则它们的传递到callback
的值是map
方法遍历到它们的那一时刻的值;而被删除的元素将不会被访问到。
代码示例
下面的代码创建了一个新数组,值为原数组中对应数字的平方根。
const numbers = [1, 4, 9];
const roots = numbers.map(Math.sqrt);
// Math.sqrt(x)
console.log(numbers);
// [1, 4, 9]
console.log(roots);
// [1, 2, 3],
Array.prototype.push()
Array.prototype.push()
方法用于向当前数组的末尾添加一个或多个元素,并返回新的数组长度。
语法
语法:
arr.push( item1 [, items...] )
类型声明:
interface Array<T> {
push(...items: T[]): number;
}
参数说明:
参数 | 说明 | 类型 |
---|---|---|
item1 | 添加元素 | any |
itemN | 添加的其他元素 | any |
如果添加的元素类型为数组类型,仍然会被当作一个元素看待,只是这个元素是数组类型而已。如果要合并两个数组,请使用 concat()
函数。
返回值:
返回添加元素后的数组长度。
方法说明
当向数组中添加新的元素时,数组的 length
属性也会随之改变。一般而言,数组的 length
属性将会加 N
( N
为添加的元素个数)。
push()
方法有意具有通用性。该方法和 call()
或 apply()
一起使用时,可应用在类似数组的对象上。push()
方法根据 length 属性来决定从哪里开始插入给定的值。如果 length
不能被转成一个数值,则插入的元素索引为 0,包括 length
不存在时。当 length
不存在时,将会创建它。
代码示例
基本用法
const foo = ['a', 'b'];
const bar = foo.push('c', 'd');
console.log(foo);
// ['a', 'b', 'c', 'd']
console.log(bar);
// 4
Array.prototype.pop()
Array.prototype.pop()
方法用于移除数组最后一个成员,并返回该数组成员。
语法
语法:
arr.pop();
类型声明:
interface Array<T> {
pop(): T | undefined;
}
返回值:
返回被移除的数组成员。如果该数组为空(没有任何元素),则返回 undefined
。
方法说明
- 该方法和
call()
或apply()
一起使用时,可应用在类数组对象上。pop
方法根据length
属性来确定最后一个元素的位置。如果不包含length
属性或length
属性不能被转成一个数值,会将length
置为 0,并返回undefined
。 - 由于该方法会移除数组中的最后一个元素,数组的
length
属性也会随之改变(如果数组中有元素的话),一般而言,数组的length
属性将会减 1。 - 如果你在一个空数组上调用
pop()
,它返回undefined
。
代码示例
基本用法
let foo = ['a', 'b', 'c', 'd'];
let popped = foo.pop();
console.log(foo);
// ['a', 'b', 'c', 'd']
console.log(popped);
// 'd'
Array.prototype.sort()
Array.prototype.sort()
方法用于将数组对象的成员按指定顺序进行排序,并返回排序后的数组。
语法
语法:
arr.sort(compareFn);
类型声明:
interface Array<T> {
sort(compareFn?: (a: T, b: T) => number): this;
}
参数说明:
参数 | 说明 | 类型 |
---|---|---|
compareFn | (可选)指定如何比较元素顺序的函数名称 | function |
返回值:
返回排序后的数组对象。
在排序过程中,并不会创建新的数组对象,返回的数组对象就是经过排序后的当前数组本身。
方法说明
如果省略 compareFn
参数,元素将按 ASCII 字符顺序的升序进行排列。ASCII 字符表
如果提供了 compareFn
参数,那么该函数必须返回下列值之一:
- 如果所传递的第一个参数小于第二个参数,则返回负值。
- 如果两个参数相等,则返回零。
- 如果第一个参数大于第二个参数,则返回正值。
比较函数格式如下:
function compare(a, b) {
if (a is less than b by some ordering criterion) {
return -1;
}
if (a is greater than b by the ordering criterion) {
return 1;
}
return 0;
}
代码示例
基本用法
const foo = ['b', 'c', 'a'];
fruit.sort();
// ['a', 'b', 'c']
const bar = [1, 10, 21, 2];
bar.sort();
// [1, 10, 2, 21]
注意 10 在 2 之前,因为在 Unicode 指针顺序中 "10"
在 "2"
之前。
const baz = ['word', 'Word', '1 Word', '2 Words'];
baz.sort();
// ['1 Word', '2 Words', 'Word', 'word']
在 Unicode 中,数字在大写字母之前,大写字母在小写字母之前。
总结
在本篇博客中,我们一起探索了JavaScript内置对象,比如:Object、Array、全局对象、String和Funtion。JavaScript是一门非常强大且广泛应用的编程语言。掌握了这些基本的语法和概念,你已经具备了入门JavaScript编程的基础。未来,你将能够创建更加交互性的网页,实现更多惊艳的动态效果,甚至搭建出属于自己的Web应用。但这只是一个开始,还有许多更深入的主题等待你去探索。
后续我们这个前端专栏还会讲述ES6、垃圾回收、js算法技巧、Vue入门实战、React实战、前端面试题等等文章,如果您感兴趣的话,欢迎点赞三连并关注我以及我的前端专栏,我们下期文章再见。