JS对象

134 阅读6分钟

对象

定义

  • 无序的数据集合
  • 键值对的集合
  • 拥有属性和方法的数据
  • 可以说对象是变量的容器

写法

let obj = { 'name': 'frank', 'age': 18}
let obj = new Object({'name': 'frank'})
console.log({'name': 'frank', 'age': 18})

细节

  • 键名是字符串,不是标识符,可以包含任意字符
  • 引号可以省略,省略之后,省略之后就只能写标识符
  • 就算引号省略了,键名也还是字符串
  • 要用变量的值用[]把键名括起来
  • 属性名:每个key都是对象的属性名
  • 属性值:每个value都是对象的属性值
  • 所有属性名会自动变成字符串

变量做属性名

  • 之前都是用常量做属性名
  • let p1 = 'name'
  • let obj = {p1:'frank'},这样写,属性名为'p1'
  • let obj = {[p1]:'frank'},这样写,属性名为name
  • 不加 []的属性名会自动变成字符串
  • 加了[]则会变成变量求值
  • 值如果不是字符串,则会自动变成字符串
  • 除了字符串,symbol也能做属性名

对象的隐藏属性

  • JS中每一个对象都有一个隐藏属性
  • 这个隐藏属性储存着共有属性组成的对象的地址
  • 这个共有属性组成的对象叫做原型

增删改查

删除属性

  • delete obj.xxx或 delete obj['xxx'] :即可删除obj的xxx属性,属性名和属性值同时删除
  • obj.xxx = undefined只会删除属性值,不会删除属性名
  • 含有属性名,但是值为undefined: 'xxx' in obj && obj.xxx === undefined
  • 'xxx' in obj 如果为true表示还在 false表示删除

读属性

  • console.dir(xxx)以目录的形式打印出来所有属性可以查看共有属性
  • Object.keys(xxx)查看所有键名
  • Object.values(xxx)查看所有值
  • Object.entries(xxx)查看所有属性名和值
  • 判断一个属性是自己的还是共有的:obj.hasOwnProperty('toString')
  • 查看属性:
  • 中括号语法: obj['key']
  • 点语法: obj.key
  • 读的时候可以访问原型

原型

  • 每个对象都有原型
  • 原型里面所有的属性都是共有的
  • 对象的原型也是对象,
  • 共有属性的原型现在被人为指定为null
  • obj = {}为所有对象的原型,这个原型包含所有对象的共有属性,是对象的根

修改或增加属性(写属性)

  • Object.assign(obj,{age:18,gender:'man'}) 批量赋值
  • let obj = {name = 'frank'}
  • obj.name = 'frank',这里的name是字符串
  • obj[name]这里的name是变量
  • obj['name'] = 'frank'
  • obj['na'+'me'] = 'frank'
  • let key = 'name'; obj[key] = 'frank'
  • 无法通过自身修改或增加共有属性
  • 要修改原型 window.Object.prototype.toString = 'xxx',一般不要修改原型
  • 修改隐藏属性:
  • let obj = Object.create(common)
  • obj.name = 'frank'

new X()自动做四件事情

  • 自动创建新对象、
  • 自动为空对象关联原型,原型地址指定为X.prototype
  • 自动将空对象作为this关键字运行构造函数
  • 自动return this
  • new后面的函数,使用名词形式
  • 如new Person()
  • 其他函数一般使用动词开头
  • createSquare(5)

构造函数X

  • 用来构造对象的函数叫做构造函数
  • X函数本身负责给对象本身添加属性
  • X.prototype对象负责保存对象的共用属性
  • 所有构造函数首字母大写
  • 所有被构造出来的对象,首字母小写

JS里面唯一的公式

如何确定一个对象的原型?

你是谁构造的你的原型就是谁的prototyp)属性对应的对象

原型公式:对象.proto_ === 其构造函数.prototype

对象分类

Object创建出来的对象是最没有特色的

类型 VS 类

  • 类型是JS数据的分类,一共有7种,四基两空一对象
  • 类 是针对于对象的分类有无数种,常见的有Array、Function、Date等

数组对象

定义一个数组

  • let arr = [1,2,3]
  • let arr = new Array(1,2,3) //元素为1,2,3
  • let arr = new Array(3) //长度为3

数组对象的自身属性

  • '0', '1', '2', '3', 'length' 属性名都是字符串

数组对象的共用属性

  • shift 删除数组第一个元素,返回数组的长度

函数对象

定义一个函数

  • function fn(x,y){return x+y}
  • let fn = new Function('x','y','return x+y')

函数对象的自身属性

  • name,length

共有属性

  • apply/call/bind/

  • window的构造者是Window
  • window.Object是由window.Function构造出来的
  • 所有的函数都是window.Function构造出来的
  • window.Function是由window.Function构造出来的


JS数组

JS其实没有真正的数组,只是用对象模拟数组

JS的数组不是典型的数组

典型的数组

  • 元素的数据类型相同
  • 连续的内存存储
  • 通过数字下表获取元素

JS的数组

  • 元素的数据类型可以不同
  • 内存不一定是连续的(对象是随机存储的)
  • 不能通过数字下标
  • 意味着数组可以有任何的key


创建一个数组

新建

  • let arr = [1,2,3]
  • let arr = new Array(1,2,3)

转化

  • let arr = '1,2,3'.split(;)
  • let arr = '123'.split('')
  • Array.from('123')这个对象有0123下标有length属性才可以变成数组

伪数组

  • let divList = document.querySelectorAll('div')再用Array.from使其变成数组
  • 伪数组的原型链中没有数组的原型

合并数组

  • arr3.concat(arr4) 创建一个新数组,之前的不变
  • arr5.slice(2),从第三个位置开始切断之前的没有创建新的数组之前的不变
  • 可以使用slice(0)复制一个数组
  • JS只提供浅拷贝

删元素

跟对象一样

  • let arr = ['a','b','c']
  • delete arr[0]
  • arr //[empty,'b','c']
  • 删除元素之后,数组长度不变
  • 稀疏数组

直接修改length可以删除元素

  • arr.length = 2
  • 会删除第二个元素之后的元素

删除头部的元素

  • arr.shift()
  • arr被修改,并返回被删元素

删除尾部的元素

  • arr.pop() //arr被修改,并返回被删元素

删除中间元素

  • arr.splice(index,1)//删除index位置的元素
  • arr.splice(index,1,'x')//并在删除位置添加'x'
  • arr.splice(index,1,'x','y')//并在删除位置添加'x''y'
  • arr.splice(index,number)//index指从第几个开始删除,number指从该位置起删除几个
  • 一个对象提供的函数就叫API

查看所有元素

查看所有属性名

  • let arr = [1,2,3,4,5]
  • Object.keys(arr)

for循环访问

for(let i = 0; i < arr.length; i++){
  console.log(`${i}: ${arr[i]`)
}

forEach

arr.forEach(function(item,index){console,log(`${index}: ${item}`)})

区别是上面:for里面有break,continue但forEach不支持,for循环是关键字不是函数,是块

查看单个属性

  • arr[0]

索引越界

  • arr[arr.length] === undefined
  • arr[-1] === undefined

元素是否在这个数组中

  • arr.indexOf(item) 不是-1就证明存在

使用条件查找元素

  • arr.find(function(x){ return x%2 === 0})
  • arr.findOf(item => item&2 ===0)

使用条件查找元素的索引

  • arr.findIndex(item => item%2 ===0) //找第一个偶数索引

增加数组中的元素

在尾部加元素

  • arr.push(newItem) //修改arr,并返回新长度
  • arr.push(item1,item2)

在头部加元素

  • arr.unshift(newItem)
  • arr.unshift(item1,item2)

在中间添加元素

  • arr.splice(index,0,'x')
  • arr.splice(index,0,'x','y')

反转顺序

  • arr.reverse() //修改原来的数组为反转数组
  • 反转字符串
let s = 'abcde'
s.splite('')
s.splite('').reverse()
s.splite('').reverse().join('')
// "ebcda"

排序

  • arr.sort() //变成从小到大
  • 自定义顺序: arr.sort((a,b) => a-b)

数组变换

map

  • n变n
  • arr.map(item => item*item)

filter

  • n变少
  • arr.filter(item => item %2 ===0 ? ture : false)
  • arr.filter(item => item %2 ===0 ) //上下等价

reduce

  • n变1
  • arr.reduce((sum, item) => { return sum+item } , 0) //return的值作为下一次的初始值