一、创建对象
方式1:字面量(方便)
var obj = {
a: 1, b: 2};
方式2:构造函数(万物皆对象)
var obj2 = new Object();
方式2扩展:构造函数传递参数
var tmpObj2 = {
c: 3, d: 4 };
var obj2 = new Object(tmpObj2);
console.log(obj2)
console.log(tmpObj2 === obj2) // 结果为 true
注意:
MDN文档:
- 如果不传递,或者传递空对象之类的(null 或者 undefined),返回默认的空对象
- 如果传递有值的内容,则返回该对象
方式3:定制化创建对象(依赖原型)
Object.create(对象,{ 属性名: 属性描述其对象})
// 模板 个性化配置
var obj3 = Object.create({
f: 1},{
// 定制化属性 一个属性配置
myAge: {
value: 25,
// 是否可写
writable: false
}
})
console.log(obj3);
方式3扩展一: 也可以后续在对属性进行定义
先用Object.create({})
,再用Object.defineProperty()
定义属性
var obj4 = Object.create({
})
Object.defineProperty(obj4,'myAge',{
value: 26,
// 是否可写
writable: true
})
console.log(obj4)
方式3扩展二:其他配置属性
- set
、get
var obj5 = Object.create({
},{
// 一个个属性配置
myAge: {
set(setVal){
console.log('数据劫持!', setVal)
},
get(){
cosnole.log('获取数据!' )
return '长大了'
}
}
})
console.log(obj5)
- configurable
、enumerable
请注意,重点来了:
- 当我们用 “常用的方式”(
let user = {name: "John"};
)创建一个属性时,它们默认都为true
- 但是当我们使用 “非常用方式”(
let user = {}; Object.defineProperty(user, 'name',{value: 'John'})
)创建时,他们默认是false
- 具体原因大家可以看这个链接内容
var obj6 = Object.create({
},{
myAge: {
value: 1,
// configurable:不可配置标志(configurable:false)是否可以使用delete,能否改变特性,能否修改访问器属性,false为不可重新定义【Object.defineProperty】
configurable: false,
// enumerable:不可枚举标志 是否可以枚举出内部属性for(let key in obj6) Object.keys|values
enumerable: false,
}
}
// 1. enumerable:false 影响下面代码
for(var key in obj6){
console.log(key) // 控制台无输出
console.log(obj6[key]) // 控制台无输出
}
// 2. configurable 影响下面的代码
Object.defineProperty(obj6,'myAge',{
value: 2,
}) // 控制台报错: TypeError
delete obj6.myAge // 控制台报错:TypeError
方式4:附加Object.assign()
// 对于原有对象的属性附加
var obj7 = Object.assign({
}, {
a: 1})
console.log(obj7)
方式5:使用现有对象构造器来创建
方式5.1:new
+ constructor
// new Object()
var obj8 = new Object.constructor()
console.log(obj8) // obj7的类型和obj8类型一样
方式5.2:ES6新加了类型反射
,也可使用API来实现上述Reflect.construct
+ constructor
var obj9 = Reflect.construct(obj8.constructor,[])
console.log(obj9)
二、操作对象属性
1、设置
var obj1 = {
};
var str = 'abc';
obj1.a = '1'; // 添加一个属性
// 字面量属性名
obj1['ab'] = 'abc';
// 变量属性名
obj1[str] = 'str';
// 测试
obj1.str = '999';
console.log(obj1);
2、变量获取
console.log(obj1['abc'], obj1['str']) // str 999
3、遍历对象
方式一:以 key 遍历
for(let key in obj1){
console.log('key', key);
console.log('value1', obj1[key]);
}
方式二:以 value 遍历
var arr = [1, 2, 3, 4]
for(let value of arr){
console.log('value2:',value)
}
注意:这里不能是对象 obj1,换成对象的话会报错,不可迭代
原因: ES6 中引入了Iterator
,只有提供了 Iterator 接口的数据类型才可以使用for-of
来循环遍历,而Array
、Set
、Map
、某些类数组如arguments
等数据类型都默认提供了Iterator
接口,所以它们可以使用 for-of 来进行遍历
方式三:如果非要使用对象的val遍历的话,ES6加入的Object.values()
var vals = Object.values(obj1)
cosnole.log(vals)
4、删除对象属性
delete obj1.a;
// 或者
Reflect.deleteProperty(obj1, 'a')
5、增加对象属性
obj1.addKey1 = '添加的第1个key属性';
Object.assign(obj1, {
addKey2: '添加的第2个key属性'});
Reflect.set(obj1, 'addKey3', '添加的第3个key属性');
console.log(obj1);
小结:
- Reflect反射类,提供了一些静态方法,
类名.调用方法
- 创建对象:
Reflect.construct(构造函数, [参数])
,类似于new
构造函数- 设置属性:
Reflect.set(对象, 属性名, 值)
- 删除属性:
Reflect.deleteProperty(对象, 属性名)
,类似于delete
可以封装中间层,便于代码维护:
var fn = Reflect.deleteProperty;
// delete 作为中间层
function myDelete(){
// 自己的一些行为
fn()
}
三、操作数组方法
创建数组
var i = 0;
var arr = new Array(100).fill(null).map(function() {
return i++
})
基本操作:增删改查
1、删除元素 splice
- 语法:
splice(start, deleteCount, item1, item2, itemN)
splice()
方法通过删除或替换现有元素或者原地添加新的元素来修改数组,并以数组形式返回被修改的内容。此方法会改变原数组。
// 从索引2开始 删除7个
arr.splice(2, 7)
2、获取元素 slice
slice()
方法返回一个新的数组对象,这一对象是一个由begin
和end
决定的原数组的浅拷贝(包括 begin,不包括end)。原始数组不会被改变。
// 还是上面的arr数组
// 1. 获取单元素
console.log(arr[50])
// 2. 获取一堆元素
console.log(arr.slice(20, 30))
// slice参数可以传递负数,负数代表 倒数第几位
console.log(arr.slice(10,-10))
3、插入元素
- 中间插入
// 1. 连续插入,多余的内容为空
arr[200] = 123
console.log(arr)
// 2. 从50开始,删除0个元素,并加入 'a', 'b', 'c', 'd', 'e'
arr.splice(50, 0, 'a', 'b', 'c', 'd', 'e')
console.log(arr)
4、查找元素
console.log(arr.find(ele => ele === 25)) // 元素:25
console.log(arr.findIndex(ele => ele === 25)) // 索引:25
压入和弹出系列(首尾)
1. 首尾压入
// 头部压入
arr.unshift(-1)
// 尾部压入
arr.push('last')
2、收尾弹出
// 头部弹出(默认弹出第一个元素)
console.log(arr.shift())
// 尾部弹出(默认弹出最后一个元素)
console.log(arr.pop())
后续新增系列
遍历: 每个元素都遍历,查看而不修改
1. forEach
arr.forEach(function(ele, index, originalArr){
// 原数组不要改变,改变也无效
if(index == 0) console.log(originalArr)
console.log(ele, index)
console.log(this)
}) // 其内部没有处理this, 改变this指向数组
2. map返回新数组
var newArr = arr.map(function(item, index, arr){
// 返回数组中的每一个元素
// 对元素进行加工
return {
id: item;
}
})
console.log(newArr)
3. filter过滤
var newArr1 = arr.filter(function(ele, index, arr){
// return true: 留下该元素
// else false: 去除该元素
// 不涉及到新的元素内容变更
return ele % 2 === 0 //获取双数
})
console.log(newArr1)
4. every 全满足
- 判断是否每一个元素都满足条件,
- 全部满足就返回true,如果出现一个不满足,则结束循环直接返回false
var isOk = arr.every(function(item, index, arr){
return item < 50
})
console.log(isOk, arr)
5. some 一个满足
- 判断是否存在其中一个满足条件
- 如果有一个满足条件就结束循环,并返回true;全部都不满足才返回false
var isOk2 = arr.some(function(item, index, arr){
console.log("执行了some");
return item < 50
})
console.log(isOk)
6. reduce 求和
- 使用上次返回的结果与每个元素计算
var nums = [1, "2", "3", "4", 5, "6", 7, 8, 9, "10"];
var sum = nums.reduce(function(total, n){
console.log("reduce内部ele值: " + ele, "====", "reduce内部total值:", total);
console.log();
if (typeof ele === "string") return total;
return total + ele;
})
console.log("reduce外部", sum);