持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第18天,点击查看活动详情
前言
前面文章说道,在javascript中函数是第一公民,但在js不仅支持函数式编程,也支持面向对象的编程,在js中的对象是一个由键值对组成的无序集合,也就是key-value,其中key是标识,value可以是任何的值,也包括函数,当值为函数时,这个函数就是对象的方法。
创建对象的两种方式
- 使用对象字面量进行创建
let obj = {
name: 'juejin',
age:22
}
- 通过
new一个Object类的实例来创建对象
let obj = new Object()
obj.name = 'juejin'
obj.age = 22
这两种方式创建的对象都是一样的
对象属性的具体控制:Object.defineProperty()
Object类上有一个defineProperty的方法可以对对象的属性进行控制,接下来我们来一起看下吧
mdn上是这么定义的: Object.defineProperty() 方法会直接在一个对象上定义一个新属性,或者修改一个对象的现有属性,
语法
Object.defineProperty(obj, prop, descriptor)
参数
它接收入三个参数:
- obj:需要进行操作的对象
- prop:操作的对象需要定义或修改的属性的名称
- descriptor:具体的操作内容的对象
descriptor
在descriptor的对象中,分为数据属性描述符和存取属性描述符两类,我们接下来分别具体介绍下
| 属性 | configurable | enumerable | value | writable | get | set |
|---|---|---|---|---|---|---|
| 数据属性描述符 | 可以 | 可以 | 可以 | 可以 | 不可以 | 不可以 |
| 存取属性描述符 | 可以 | 可以 | 不可以 | 不可以 | 可以 | 可以 |
数据属性描述符
从上述的表格中我们可以看出来属性操作符有configurable,enumerable,value, writable可以使用,get和set不可以,我们来具体看下每个属性都是什么作用
configurable:
可以控制属性删除和是否可再次进行属性操作,默认值时false(使用new关键字创建对象时)
- 当首先设置为true的时候可以被删除
var obj = {
name:'juejin'
}
Object.defineProperty(obj,'name',{
configurable:true
})
//删除属性
delete obj.name
console.log(obj.name) //undefined
- 设置为false的时候不可以被删除
var obj = {
name:'juejin'
}
Object.defineProperty(obj,'name',{
configurable:false
})
//删除属性
delete obj.name
console.log(obj.name) //juejin
- 当设置为true的时候可以被修改特性
var obj = {
name: 'clearlove'
}
Object.defineProperty(obj, "name", {
writable: false,
enumerable: true,
configurable: true
});
//重新修改特性
Object.defineProperty(obj, "name", {
writable: true,
enumerable: true,
configurable: true
});
console.log(obj.name); //clearlove
- 当设置为false的时候不可以修改特性
var obj = {
name: 'juejin'
}
//重新修改特性
Object.defineProperty(obj, "name", {
configurable: false
});
Object.defineProperty(obj, "name", {
configurable: true
});
console.log(obj.name);
enumerable
表示该属性是否可以被枚举,默认值时false(使用new关键字创建对象时)
- 当设置为true的时候可以被枚举
var obj = {
name: 'juejin',
age: 22
}
//修改特性
Object.defineProperty(obj, "name", {
enumerable:true
});
// 进行枚举操作
let keys = Object.keys(obj)
console.log(keys)
- 当设置为false的时候不可以被枚举
var obj = {
name: 'juejin',
age: 22
}
//修改特性
Object.defineProperty(obj, "name", {
enumerable:false
});
// 进行枚举操作
let keys = Object.keys(obj)
console.log(keys)
value
就是设置属性的值 默认值为undefined (使用new关键字创建对象时)
var obj = {
name: 'juejin',
age: 22
}
//修改特性
Object.defineProperty(obj, "name", {
value: 'kaka'
});
console.log(obj.name)
注意:它不能和get同时使用
writable
表示是否可修改的对象的属性,默认值时false (使用new关键字创建对象时)
- 设置为true的时候可以修改属性
var obj = {
name: 'juejin',
age: 22
}
//修改特性
Object.defineProperty(obj, "name", {
writable: true
});
obj.name = 'kaka'
console.log(obj.name)
- 设置为false的时候不可以修改
var obj = {
name: 'juejin',
age: 22
}
//修改特性
Object.defineProperty(obj, "name", {
writable: false
});
obj.name = 'kaka'
console.log(obj.name)
存取属性描述符
它主要是指get和set,是指在对对象的属性进行存取的时候可以做一些操作
get
在属性值被获取的时候进行的操作
let obj = {
name: 'juejin',
age: 22
}
//修改特性
Object.defineProperty(obj, "name", {
get(){
console.log('我被获取了')
return 'juejin'
// return 'kaka'
}
});
console.log(obj.name)
可以用来保护某个属性,例如不让获取name的真实值
let obj = {
name: 'juejin',
age: 22,
_name: 'kaka'
}
//修改特性
Object.defineProperty(obj, "name", {
get(){
return obj._name
// return 'kaka'
}
});
console.log(obj.name)
set
当对属性设置值时,进行的操作
let obj = {
name: 'juejin',
age: 22,
_name: 'kaka'
}
//修改特性
Object.defineProperty(obj, "name", {
set(){
console.log('我被修改了')
}
});
obj.name = 'ronaldo'
Object.defineProperty()的实际用途
vue2中的数据绑定和视图渲染就用到了这个,我们来简单模拟下吧
- 准备一段简单的html代码
<input class="ip" type="text">
<div class="demo"></div>
我们要实现input输入的值同步出现在类名为demo的div中
// 模拟vue的数据驱动
let data = {
name: 'kaka'
}
let divdom = document.querySelector('.demo')
Object.defineProperty(data,'name',{
set(value){
// 设置div的值为设置的值
divdom.innerHTML = value
return value
}
})
// 监听并处理值
let inputdom = document.querySelector('.ip')
inputdom.oninput = (event) => {
let value = event.target.value
data.name = value
}
来看下页面渲染(不会做gif图,凑合看下静态截图吧)