js 对象方法

一、 字符串

方法描述
charAt()返回在指定位置的字符。
charCodeAt()返回在指定的位置的字符的 Unicode 编码。
concat()连接字符串。
indexOf()检索字符串。
match()找到一个或多个正则表达式的匹配。
replace()替换与正则表达式匹配的子串。
search()检索与正则表达式相匹配的值。
slice()提取字符串的片断,并在新的字符串中返回被提取的部分。
split()把字符串分割为字符串数组。
toLocaleLowerCase()把字符串转换为小写。
toLocaleUpperCase()把字符串转换为大写。
toLowerCase()把字符串转换为小写。
toUpperCase()把字符串转换为大写。
substr()从起始索引号提取字符串中指定数目的字符。
substring()提取字符串中两个指定的索引号之间的字符。

二、 数组

方法描述
slice[start,end)返回从原数组中指定开始下标到结束下标之间的项组成的新数组(不影响原数组)
.1 个参数:n.即:n 到末尾的所有
.2 个参数:[start,end]
splice()
.删除:2 个参数,起始位置,删除的项数 splice(0,1)从第0位删除一个
.插入:3 个参数,起始位置,删除的项数,插入的项 splice(0,0,1)从第0位删除0个,插入'1'
.替换:任意参数,起始位置,删除的项数,插入任意数量的项 splice(0,1,1)从第0位删除1个,插入'1'
pop()删除数组的最后一个元素,减少数组的长度,返回删除的值。(无参)
push()将参数加载到数组的最后,返回新数组的长度。 (参数不限)
shift()删除数组的第一个元素,数组长度减 1,返回删除的值。 (无参)
unshift()向数组的开头添加一个或更多元素,并返回新的长度。(参数不限)
sort()按指定的参数对数组进行排序 ,返回的值是经过排序之后的数组(无参/函数)
concat(3,4)把两个数组拼接起来。 返回的值是一个副本 (参数不限)
join()将数组的元素组起一个字符串,以 separator 为分隔符,省略的话则用默认用逗号为分隔符
includes()判断一个数组是否包含一个指定的值,如果是返回 true,否则 false。
indexOf()从数组开头向后查找,接受两个参数,要查找的项(可选)和查找起点位置的索引,没找到指定元素则返回 -1
lastIndexOf()从数组末尾开始向前查找,接受两个参数,要查找的项(可选)和查找起点位置的索引,没找到指定元素则返回 -1
filter()对数组中的每一项运行给定函数,返回该函数会返回 true 的项组成数组。 (不改变原数组)
forEach()对数组的每一项运行给定函数,这个方法没有返回值。 (不改变原数组)
map()对数组的每一项运行给定函数,返回每次函数调用的结果组成的数组。 (不改变原数组)
every()对数组中的每一项运行给定函数,如果该函数对每一项都返回 true,则返回 true。 (不改变原数组)
some()对数组的每一项运行给定参数,如果该函数对任一项返回 true,则返回 true。(不改变原数组)
reduce()和 reduceRight()缩小数组的方法,这两个方法都会迭代数组的所有项,然后构建一个最终返回的值。
from从一个类似数组或可迭代对象创建一个新的,浅拷贝的数组实例
find()返回符合传入测试(函数)条件的数组元素。
findIndex()返回符合传入测试(函数)条件的数组元素索引。

实例:

var arr = [1, 2, 3, 4, 5, 4, 3, 2, 1];
// 1.every()
var every = arr.every(function (item, index, array) {
  return item > 2;
});
console.log(every); // false

// 2.some()
var some = arr.some(function (item, index, array) {
  return item > 2;
});
console.log(some); // true

// 3.filter()
var filter = arr.filter(function (item, index, array) {
  return item > 2;
});
console.log(filter); // [3,4,5,4,3]

// 4.map()
var map = arr.map(function (item, index, array) {
  return item * 2;
});
console.log(map); // [2,4,6,8,10,8,6,4,2]

// 5.forEach()
var forEach = arr.forEach(function (item, index, array) {
  // 执行某些操作
});

// 6. reduce
var values = [1, 2, 3, 4, 5];
var sum = values.reduce(function (init, current, index, array) {
  return prev + cur;
});
console.log(sum); // 15

// 7. from
Array.from("foo");
// ["f", "o", "o"]
Array.from([1, 2, 3], (x) => x + x);
// [2, 4, 6]

三、 Math

方法描述例子
Math.IP圆周率console.log(Math.PI);输出 3.1415......
Math.SQRT2根号 2console.log(Math.SQRT2);输出根号 2
Math.SQRT1_2根号根号 1/2console.log(Math.SQRT1_2);输出根号 1/2
Math.pow(num,n)num 的 n 次方console.log(Math.pow(2,3));输出 2 的 3 次方 8
Math.sqrt(num)num 开平方console.log(Math.sqrt(4));输出 4 开平方 2
Math.cbrt(num)num 开立方console.log(Math.cbrt(8));输出 8 开立方 2
Math.hypot(n1,n2,n3...)(n1 平方+n2 平方+..)开方console.log(Math.hypot(3,4,5));输出(9+16+25)开方 根号 50
Math.random()[0,1)的随机数console.log(Math.random());输出[0,1)之间的一个随机数
Math.ceil(num)对 num 进行向上取整console.log(Math.ceil(0.01));输出 1
Math.floor(num)对 num 进行向下取整console.log(Math.floor(0.999));输出 0
Math.round(num)对 num 进行四舍五入(四舍五入)console.log(Math.round(0.5));输出 1
Math.max(n1,n2,n3,..)取 n1,n2,n3...之间的最大值console.log(Math.max(1,5,7));输出 7
Math.min(n1,n2,n3,..)取 n1,n2,n3...之间的最小值console.log(Math.min(1,5,7));输出 1
Math.sin(角度)求正弦console.log(Math.sin(Math.PI/2);输出 1
Math.cos(角度)求余弦console.log(Math.cos(Math.PI);输出-1
Math.tan(角度)求正切console.log(Math.tan(Math.PI/4);输出 0.99999999
Math.abs(num)求 num 的绝对值console.log(Math.abs(-1));输出 1
Math.max.apply(null,[n1,n2,n3])传入的是数组,取 [n1,n2,n3]之间的最大值console.log(Math.max.apply(null,[1,6,3]);输出 6

四、 正则

方法描述
compile编译正则表达式。
exec检索字符串中指定的值。返回找到的值,并确定其位置。
test检索字符串中指定的值。返回 true 或 false。
search检索与正则表达式相匹配的值。
match找到一个或多个正则表达式的匹配。
replace替换与正则表达式匹配的子串。
split把字符串分割为字符串数组。

五、 Date

方法描述
Date()获取当前时间(带有格式的)
Date("年月日 时分秒")指定到某个时间
Date(null)指定 1970-1-1 00 : 00 : 00
date.getTime()将 date 转换成毫秒(时间戳)
date.getFullYear()获取年
date.getMonth()+1获取月(默认从 0 开始,要+1)
date.getDate()获取日
date.getDay()获取星期(从星期日开始,星期日是 0)
date.getHours()获取时
date.getMinutes()获取分
date.getSeconds()获取秒
date.getMilliseconds()获取毫秒

1. 日期格式化

//日期格式化封装,传入date  "var date = new Date()'和 格式"-"或 "/",默认为'-'
function formatDate(date, format) {
  let myyear = date.getFullYear();
  let mymonth = date.getMonth() + 1;
  let mydate = date.getDate();
  if (mymonth < 10) {
    mymonth = "0" + mymonth;
  }
  if (mydate < 10) {
    mydate = "0" + mydate;
  }
  switch (format || "-") {
    case "-":
      return myyear + "-" + mymonth + "-" + mydate;
      break;
    case "/":
      return myyear + "/" + mymonth + "/" + mydate;
      break;
  }
}

2. 日期时间格式化

//日期时间格式化封装,传入date  var date = new Date();
function formatDateTime(date) {
  let myyear = date.getFullYear();
  let mymonth = date.getMonth() + 1;
  let mydate = date.getDate();
  let myHours = date.getHours();
  let myMinutes = date.getMinutes();
  let mySeconds = date.getSeconds();
  if (mymonth < 10) {
    mymonth = "0" + mymonth;
  }
  if (mydate < 10) {
    mydate = "0" + mydate;
  }
  if (myHours < 10) {
    myHours = "0" + myHours;
  }
  if (myMinutes < 10) {
    myMinutes = "0" + myMinutes;
  }
  if (mySeconds < 10) {
    mySeconds = "0" + mySeconds;
  }
  return (
    myyear +
    "年" +
    mymonth +
    "月" +
    mydate +
    "日" +
    myHours +
    "时" +
    myMinutes +
    "分" +
    mySeconds +
    "秒"
  );
}

六、 Object

参考文章:JavaScript Object 对象方法open in new window(https://www.jianshu.com/p/69424b107f4a)

方法描述
Object.assign()用于将所有可枚举属性的值从一个或多个源对象复制到目标对象。它将返回目标对象。
Object.create()创建一个新对象,使用现有的对象来提供新创建的对象的__proto__
Object​.keys()返回一个由一个给定对象的自身可枚举属性组成的数组,数组中属性名的排列顺序和使用 for...in 循环遍历该对象时返回的顺序一致 。
Object​.values()返回一个给定对象自身的所有可枚举属性值的数组,值的顺序与使用 for...in 循环的顺序相同 ( 区别在于 for-in 循环枚举原型链中的属性 )。
Object​.entries()返回一个给定对象自身可枚举属性的键值对数组,其排列与使用 for...in 循环遍历该对象时返回的顺序一致(区别在于 for-in 循环也枚举原型链中的属性)。
Object​.freeze()Object.freeze() 方法可以冻结一个对象。一个被冻结的对象再也不能被修改
Object​.from​Entries()Object.fromEntries() 把键值对列表转换为一个对象。Object.fromEntries() 是 Object.entries 的反转。
Object.is()判断两个值是否是相同的值。
Object​.isExtensible()判断一个对象是否是可扩展的(是否可以在它上面添加新的属性)。
Object​.isFrozen()判断一个对象是否被冻结。
// Object.entries(obj)
const obj = { foo: "bar", baz: 42 };
console.log(Object.entries(obj)); // [ ['foo', 'bar'], ['baz', 42] ]

//Object​.from​Entries()
const map = new Map();
map.set("foo", "bar");
map.set("baz", "1122");
const obj = Object.fromEntries(map);
console.log(obj); // { foo: "bar", baz: 1122 }

in 运算符返回一个布尔值,表示一个对象是否具有某个属性。它不区分该属性是对象自身的属性,还是继承的属性。

1. 理解 Object.defineProperty 的作用

对象是由多个名/值对组成的无序的集合。对象中每个属性对应任意类型的值。 定义对象可以使用构造函数或字面量的形式:

var obj = new Object;  //obj = {}
obj.name = "张三";  //添加描述
obj.say = function(){};  //添加行为
除了以上添加属性的方式,还可以使用Object.defineProperty定义新属性或修改原有的属性。

Object.defineProperty()

语法:

Object.defineProperty(obj, prop, descriptor);
// 参数说明:

// obj:必需。目标对象
// prop:必需。需定义或修改的属性的名字
// descriptor:必需。目标属性所拥有的特性
// 返回值:

// 传入函数的对象。即第一个参数obj
// 针对属性,我们可以给这个属性设置一些特性,比如是否只读不可以写;是否可以被for..in或Object.keys()遍历。

// 给对象的属性添加特性描述,目前提供两种形式:数据描述和存取器描述。
1. 数据描述

当修改或定义对象的某个属性的时候,给这个属性添加一些特性:

var obj = {
  test: "hello",
};
//对象已有的属性添加特性描述
Object.defineProperty(obj, "test", {
  configurable: true | false,
  enumerable: true | false,
  value: 任意类型的值,
  writable: true | false,
});
//对象新添加的属性的特性描述
Object.defineProperty(obj, "newKey", {
  configurable: true | false,
  enumerable: true | false,
  value: 任意类型的值,
  writable: true | false,
});

// 数据描述中的属性都是可选的,来看一下设置每一个属性的作用。
2. value

属性对应的值,可以使任意类型的值,默认为 undefined

var obj = {};
//第一种情况:不设置value属性
Object.defineProperty(obj, "newKey", {});
console.log(obj.newKey); //undefined
// ------------------------------
//第二种情况:设置value属性
Object.defineProperty(obj, "newKey", {
  value: "hello",
});
console.log(obj.newKey); //hello
3. writable

属性的值是否可以被重写。设置为 true 可以被重写;设置为 false,不能被重写。默认为 false。

var obj = {};
//第一种情况:writable设置为false,不能重写。
Object.defineProperty(obj, "newKey", {
  value: "hello",
  writable: false,
});
//更改newKey的值
obj.newKey = "change value";
console.log(obj.newKey); //hello

//第二种情况:writable设置为true,可以重写
Object.defineProperty(obj, "newKey", {
  value: "hello",
  writable: true,
});
//更改newKey的值
obj.newKey = "change value";
console.log(obj.newKey); //change value
4. enumerable

此属性是否可以被枚举(使用 for...in 或 Object.keys())。设置为 true 可以被枚举;设置为 false,不能被枚举。默认为 false。

var obj = {};
//第一种情况:enumerable设置为false,不能被枚举。
Object.defineProperty(obj, "newKey", {
  value: "hello",
  writable: false,
  enumerable: false,
});

//枚举对象的属性
for (var attr in obj) {
  console.log(attr);
}
//第二种情况:enumerable设置为true,可以被枚举。
Object.defineProperty(obj, "newKey", {
  value: "hello",
  writable: false,
  enumerable: true,
});

//枚举对象的属性
for (var attr in obj) {
  console.log(attr); //newKey
}
5. configurable

是否可以删除目标属性或是否可以再次修改属性的特性(writable, configurable, enumerable)。设置为 true 可以被删除或可以重新设置特性;设置为 false,不能被可以被删除或不可以重新设置特性。默认为 false。

这个属性起到两个作用:

  • 目标属性是否可以使用 delete 删除
  • 目标属性是否可以再次设置特性
//-----------------测试目标属性是否能被删除------------------------
var obj = {};
//第一种情况:configurable设置为false,不能被删除。
Object.defineProperty(obj, "newKey", {
  value: "hello",
  writable: false,
  enumerable: false,
  configurable: false,
});
//删除属性
delete obj.newKey;
console.log(obj.newKey); //hello

//第二种情况:configurable设置为true,可以被删除。
Object.defineProperty(obj, "newKey", {
  value: "hello",
  writable: false,
  enumerable: false,
  configurable: true,
});
//删除属性
delete obj.newKey;
console.log(obj.newKey); //undefined

//-----------------测试是否可以再次修改特性------------------------
var obj = {};
//第一种情况:configurable设置为false,不能再次修改特性。
Object.defineProperty(obj, "newKey", {
  value: "hello",
  writable: false,
  enumerable: false,
  configurable: false,
});

//重新修改特性
Object.defineProperty(obj, "newKey", {
  value: "hello",
  writable: true,
  enumerable: true,
  configurable: true,
});
console.log(obj.newKey); //报错:Uncaught TypeError: Cannot redefine property: newKey

//第二种情况:configurable设置为true,可以再次修改特性。
Object.defineProperty(obj, "newKey", {
  value: "hello",
  writable: false,
  enumerable: false,
  configurable: true,
});

//重新修改特性
Object.defineProperty(obj, "newKey", {
  value: "hello",
  writable: true,
  enumerable: true,
  configurable: true,
});
console.log(obj.newKey); //hello

除了可以给新定义的属性设置特性,也可以给已有的属性设置特性

//定义对象的时候添加的属性,是可删除、可重写、可枚举的。
var obj = {
  test: "hello",
};

//改写值
obj.test = "change value";

console.log(obj.test); //'change value'

Object.defineProperty(obj, "test", {
  writable: false,
});

//再次改写值
obj.test = "change value again";

console.log(obj.test); //依然是:'change value'

!> 提示:一旦使用 Object.defineProperty 给对象添加属性,那么如果不设置属性的特性,那么 configurable、enumerable、writable 这些值都为默认的 false

var obj = {};
//定义的新属性后,这个属性的特性中configurable,enumerable,writable都为默认的值false
//这就导致了neykey这个是不能重写、不能枚举、不能再次设置特性
//
Object.defineProperty(obj, "newKey", {});

//设置值
obj.newKey = "hello";
console.log(obj.newKey); //undefined

//枚举
for (var attr in obj) {
  console.log(attr);
}

设置的特性总结:

  • value: 设置属性的值
  • writable: 值是否可以重写。true | false
  • enumerable: 目标属性是否可以被枚举。true | false
  • configurable: 目标属性是否可以被删除或是否可以再次修改特性 true | false
6. 存取器描述

当使用存取器描述属性的特性的时候,允许设置以下特性属性:

var obj = {};
Object.defineProperty(obj,"newKey",{
    get:function (){} | undefined,
    set:function (value){} | undefined
    configurable: true | false
    enumerable: true | false
});

注意:当使用了 getter 或 setter 方法,不允许使用writablevalue这两个属性

getter/setter

当设置或获取对象的某个属性的值的时候,可以提供getter/setter方法。

  • getter 是一种获得属性值的方法
  • setter 是一种设置属性值的方法。

在特性中使用 get/set 属性来定义对应的方法。

var obj = {};
var initValue = "hello";
Object.defineProperty(obj, "newKey", {
  get: function () {
    //当获取值的时候触发的函数
    return initValue;
  },
  set: function (value) {
    //当设置值的时候触发的函数,设置的新值通过参数value拿到
    initValue = value;
  },
});
//获取值
console.log(obj.newKey); //hello

//设置值
obj.newKey = "change value";

console.log(obj.newKey); //change value

!> 注意:get 或 set 不是必须成对出现,任写其一就可以。如果不设置方法,则 get 和 set 的默认值为 undefined

!> configurable 和 enumerable 同上面的用法。

7. 兼容性

在 ie8 下只能在 DOM 对象上使用,尝试在原生的对象使用 Object.defineProperty() 会报错。

2. JS 对象属性中 get/set 与 getter/setter 是什么

在 js 属性描述符这部分有几个较难理解的名词概念,本文旨在描述对它们的理解,主要包括:[[Get]]/[[Put]]get/setgetter/setter几个概念的阐述,数据属性和访问器属性。

(1). 属性

首先我们要搞清楚属性的概念,属性是存储在特定命名位置的值,是对象的内容,属性并不直接存储在对象容器内部。属性有两种类型:数据属性和访问器属性。属性具备了属性描述符,用来描述属性拥有的特性。

(2). 属性描述符

属性描述符用来描述属性特性的(只有在内部才能用的特性),配置属性是否可读,是否可写,是否可枚举,值是多少,读写。

(3). 属性描述符对象

Object.definePrOperty(obj, "a", {
  value: 2,
  writable: true,
  configurable: true,
});

第三个参数就是属性描述符对象 ,首先它是个对象,它有自己的属性,其次它是属性 a 的属性描述符,用来配置属性。

定义这些特性为了实现 JavaScript 引擎用的,因此再 JavaScript 中不能直接访问它们。为了表示特征是内部值,ES 规范把它们放在了两对方括号中,例如[[Enumerable]]

访问器属性不能直接定义,必须使用Object.defineProperty()来定义。

(4). 数据属性

数据属性包含一个数据值的位置。在这个位置可以读取和写入值。共有四个描述其行为的特征:

  • [[Configurable]]:配置,表示能否删除修改属性的特性,或者把属性修改为访问器属性。默认true
  • [[Enumerable]]:枚举,表示能否通过 for-in 循环返回属性。默认true
  • [[Writable]]:可写,表示能否修改属性值。默认true
  • [[Value]]:属性的数据值。读写属性值从该位置。默认undefined

(5). 访问器属性

访问器属性不包含数据值;它们包含一对 getter 和 setter 函数。共有四个描述其行为的特征:

  • [[Configurable]]:配置,表示能否删除修改属性的特性,或者把属性修改为访问器属性。默认 true
  • [[Enumerable]]:枚举,表示能否通过 for-in 循环返回属性。默认 true
  • [[Get]]:在读取属性值时调用的函数。默认 undefined
  • [[Set]]:在写入属性值时调用的函数。默认 undefined

当个一个属性定义 getter、setter 或者两者都有时,这个属性就成了访问器属性

知道属性分类之后,下面我们逐一解答开头的几个问题:

[[Get]]/[[Put]]是什么 首先要明确一点,[[Get]][[Put]]是对象默认的内置操作,可以理解为算法函数。它是在访问属性时的操作,例如通过 obj.a访问 a 属性时就是实现了[[Get]]操作,它会先找到相同的属性名,找到才要返回属性值。

没有找到就会按照[[Get]]算法的设计,沿着原型链找,找不到会返回 undefined。

[[Put]]被触发时,取决于许多因素,最重要的有对象中是否已经存在这个属性。如果已经存在,算法大致会检查下面这些内容:

属性是否是访问描述符?如果是并且存在 setter 就调用 setter 属性的数据描述符中 writable 是否是 false?如果是,在非严格模式下静默失败,在严格模式下抛出 TypeError 异常。 如果都不是,将该值设置为属性的值。

(6). get/set 和 getter/setter

[[Get]][[Set]]:当属性拥有这两个特性时,属性就是访问器属性。代表着在访问属性或者写入属性值时,对返回值做附加的操作。而这个操作就是 getter/setter 函数。

它们只能应用到单个属性上,无法应用在整个对象上。getter/setter 是隐藏函数,是访问器属性默认拥有的隐藏函数。在读取访问器属性时调用 getter,返回有效的值;在写入访问器属性时调用 setter 函数并传入新值。

不管是对象文字语法中的 get a(){...},还是的 defineProperty(..)中的显式定义,二者都会在对象中创造一个不包含值得属性,对于这个属性的访问会自动调用一个隐藏函数,它的返回值会被当做属性访问的返回值:

// javascript
var myObject = {
//给 a 定义一个 getter
get a(){
return this._a_;
},
//给 a 定义一个 setter
set a(val){
this._a_=val \*2;
}
}
myObject.a=2;
myObject.a;//4

设置 getter 会覆盖默认的[[Get]]操作,setter 会覆盖默认得[[Put]],也被称为赋值操作

实际上我们赋值([[Put]])操作中的值 2 存储到了另一个变量a中。名称a只是一种惯例,没有任何特殊行为。

(7). 总结

属性是拥有自己的特性的,主要用来描述属性是否可以进行修改枚举配置的。我们访问对象的属性时就是[[Get]]操作,写入就是[[Put]]操作,根据算法找到对应的属性。如果要对属性值进行附加操作时,就需要设置 get/set特性,此时属性也就会变成访问器属性,然后调用默认的隐藏的 getter/setter 函数对属性进行操作。然后返回属性值。这就是整个流程,vue 框架中双向绑定就是用到了这些概念来完成数据监听的,对象属性可以说是 js 中一个很核心的概念了

参考文章:https://baijiahao.baidu.com/s?id=1623144714605018773&wfr=spider&for=pc

Last Updated:
Contributors: zerojs