这个系列详细的记录对象相关的知识点
函数编程和面向对象对比
函数编程可能编写出来的方法可能不简练
1 2 3 4 5 6 7 8 9 10
| let user = [] function add(user, name) { user.push(name) } function edit(user, index, rename) { if(index < user.length) { user[index] = rename } }
|
面向对象就可省略很多的代码,比如下面的对象
1 2 3 4 5 6 7 8 9 10
| function genUser() { this.name = [] } genUser.prototype.add = function(name) { this.name.push(name) } genUser.prototype.edit = function(index, rename) { this.name[index] = rename } let userA = new genUser()
|
或者直接写成es6的代码
1 2 3 4 5 6 7 8 9 10 11
| class genUser { constructor() { this.name = [] } add() { } edit() {
} }
|
这样感觉更优雅了
引用传址
因为对象是引用类型,直接赋值只会复制地址:
1 2 3 4
| let user = {} let otherUser = user user.name = "张三" console.log(otherUser.name)
|
展开语法实现参数合并
比如:
1 2 3 4 5 6 7 8 9 10 11 12
| function upload(params) { let config = { type: "*.jpeg,*.png", size: 100000 } config = {...config, ...params} console.log(config) } console.log(upload({size: 9999}))
console.log(upload({size: 9999, type: "*.gif"}))
|
解析赋值
跳转到十个实用的ES6特性:解构赋值
函数参数解构
1 2 3 4 5
| function foo([name, age]) {} foo(["Handsome Jack", 18])
function bar(name, {sex, age}) bar("Handsome Jack", {sex: "male", age: 18})
|
对象属性的增删查改
查
使用 hasOwnProperty()
方法可以查看是否存在某个属性:
1 2 3 4
| let foo = {} foo.name = "Handsome Jack" console.log(foo.hasOwnProperty("name")) console.log(foo.hasOwnProperty("age"))
|
如果想要检查原型 __proto__
中是否拥有某个属性就需要用到 in
关键字:
1 2 3 4 5
| let foo = [] console.log(foo.hasOwnProperty("length")) console.log(foo.hasOwnProperty("push")) console.log("push" in foo)
|
读取
可以用点语法或者中括号都能访问到对象里面的某个成员。(特殊的成员只能用中括号)
1 2 3 4 5 6 7 8
| let user = { name: "张三", "my age": 18 } console.log(user.name); console.log(user["name"]); console.log(user.my age); console.log(user["my age"]);
|
不过一般都不会用上面那么奇怪的写法,而且点会更加常用
遍历
可以用 for in
遍历,这种情况下就只能用中括号了:
1 2 3 4 5 6 7
| let user = { name: "张三", "my age": 18 } for (const key in user) { console.log(user[key]) }
|
新增或者删除属性
也是直接用点语法或者中括号就行了
1 2 3 4 5 6 7 8 9
| let user = {} user["name"] = '张三' user.age = 19; user.get = function() { return `${this.name}的年龄是${this.age}` } console.log(user.get()) delete user.age console.log(user.get())
|
对象浅拷贝
浅拷贝的意思是:不能深层次的拷贝,只能拷贝第一层的基本属性(不包括对象)
使用循环
1 2 3 4 5 6 7 8 9
| let foo = { name: "foo", url: "foo.com" } let bar = {} for (const key in foo) { bar[key] = hd[key] } bar[name] = "bar"
|
使用assign方法
1 2 3 4 5 6
| let foo = { name: "foo", url: "foo.com" } let bar = Object.assign({}, foo) bar[name] = "bar"
|
展开语法
1 2 3 4 5 6
| let foo = { name: "foo", url: "foo.com" } let bar = {...foo} bar[name] = "bar"
|
深拷贝
递归实现
1 2 3 4 5 6 7
| function DeepCopy(obj) { let res = {} for (const key in obj) { res[key] = typeof obj[key] == "object" ? DeepCopy(obj[key]) : obj[key] } return res }
|
不过这个只是考虑到对象并没有考虑到数组,继续优化一下
1 2 3 4 5 6 7
| function DeepCopy(obj) { let res = obj instanceof Array ? [] : {} for (const [key, value] of Object.entries(obj)) { res[key] = typeof value == "object" ? DeepCopy(value) : value } return res }
|