对象可以使用的for of
for...of 在可迭代对象上创建一个迭代循环,其中可迭代对象的要求为对象必须实现@@iterator方法 developer.mozilla.org/zh-CN/docs/… 自己实现的kitterable对象中必须有一个[Symbol.iterator]属性,且是一个无参数的函数,返回一个对象(A), 对象(A)中有一个next属性,是一个返回带有done(boolean)和value属性的对象的函数
let iterableobj = {
i: 0,
[Symbol.iterator]: () => {
return {
next: () => {
if(iterableobj.i < 3){
iterableobj.i++
return {
value: iterableobj.i,
done: false
}
} else {
return {
value: undefined,
done: true
}
}
}
}
}
}
试验一下
for (var value of iterable) {
console.log(value);
}
// 1
// 2
// 3
for...in 遍历对象
for in 遍历对象时,会把原型链上的可枚举属性也遍历一下
let obj = {a: 1, b: 2}
Object.prototype.c = 3
for(let key in obj){
console.log(key)
}
// a
// b
// c
但是我们可以加一个Obj.hasOwnProperty()来判断一下是不是对象自身属性中具有指定的属性
let obj = {a: 1, b: 2}
Object.prototype.c = 3
for(let key in obj){
if(obj.hasOwnProperty(key)){
console.log(key)
}
}
// a
// b
Object.keys()
Object.keys()返回一个给定对象的⾃身可枚举属性组成的数组
Object.prototype.c = 3
let obj = {a: 1, b: 2}
let keys = function (obj){
let arr = []
for(let key in obj){
if(obj.hasOwnProperty(key)){
arr.push(key)
}
}
return arr
}
// a
// b
Object.values()
Object.values返回⼀个给定对象⾃身的所有可枚举属性值的数组
Object.prototype.c = 3
let obj = {a: 1, b: 2}
let values = function (obj){
let arr = []
for(let key in obj){
if(obj.hasOwnProperty(key)){
arr.push(obj[key])
}
}
return arr
}
// 1
// 2
Object.entries
Object.entries返回⼀个给定对象⾃身可枚举属性的键值对数组
Object.prototype.c = 3
let obj = {a: 1, b: 2}
let entries = function (obj){
let arr = []
for(let key in obj){
if(obj.hasOwnProperty(key)){
arr.push([key, obj[key]])
}
}
return arr
}
// [[a: 1], [b, 2]]
Object.getOwnPropertyNames()
同Object.keys()
Object.assign
浅拷贝
function shallowClone(source) {
const target = {};
for (const i in source) {
if (source.hasOwnProperty(i)) {
target[i] = source[i];
}
}
return target;
}
Array.flat
按照指定深度将数组扁平化
function flat(arr, num = 1){
console.log(num)
if(num === 0) return arr
return arr.reduce((res, val) => {
if(Array.isArray(val)){
res = res.concat(flat(val, num-1))
} else {
res = res.concat(val)
}
return res
}, [])
}
Array.includes
来判断⼀个数是否包含⼀个指定的值.
类数组转为真数组
- [...arguments]
- Array.form
- Array.prototype.slice.call(arguments)
继承
原型链继承
function Parent(name){
this.name = name
}
Parent.prototype.getName = function(){
console.log(this.name)
}
let parent = new Parent('parent')
function Child(){}
Child.prototype = parent
let child = new Child('child')
child.constructor = Child
child.getName()
缺点:
1.无法传参
2. 当属性为引用类型时,一个实例修改会对所有实例产生影响
构造函数继承
function Parent(name, food){
this.name = name
this.eat = {food}
}
function Child(name, food){
Parent.call(this, name, food)
}
let child1 = new Child('aa', 'apple')
let child2 = new Child('bb', 'orange')
缺点: 属性或者方法只能定义在构造函数内部,每次创建实例的时候,都需要创建一遍方法
组合继承
function Parent(name, food){
this.name = name
this.eat = {food}
}
Parent.prototype.actions = function(){
console.log(this.eat.food)
}
function Child(name,food){
Parent.apply(this, Array.from(arguments))
}
Child.prototype = new Parent()
Child.prototype.constructor = Child
let child1 = new Child('aa', 'apple')
let child2 = new Child('bb', 'orange')
child1.actions()
child2.actions()
缺点:调用了两次构造函数
寄生式组合继承
function Parent(name, food){
this.name = name
this.eat = {food}
}
Parent.prototype.actions = function(){
console.log(this.eat.food)
}
function Child(name,food){
Parent.apply(this, Array.from(arguments))
}
Child.prototype = Object.create(Parent.prototype)
Child.prototype.constructor = Child
let child1 = new Child('aa', 'apple')
let child2 = new Child('bb', 'orange')
child1.actions()
child2.actions()