js对象的属性
数据属性
可以直接obj.key或者obj[key]方式访问,我们平时常用的就是这种
访问器属性
包含一对儿getter和setter函数。读取访问器属性时,会调用getter函数,返回有效的值;在写入访问器属性时,会调用setter函数并传入新值。
Object.defineProperty
Object.defineProperty() 方法会直接在一个对象上定义一个新属性,或者修改一个对象的现有属性,并返回此对象。
备注:应当直接在 Object 构造器对象上调用此方法,而不是在任意一个 Object 类型的实例上调用。
/**
* Object.defineProperty() 方法会直接在一个对象上定义一个新属性,
* 或者修改一个对象的现有属性,并返回此对象。
* data 要定义属性的对象。
* key 要定义或修改的属性的名称或 Symbol 。
* obj 要定义或修改的属性描述符。
*/
Object.defineProperty(obj, 'a', {
// 这里面的参数是固定的
// configurable: false,//值为 true 时,该属性的描述符才能够被改变,同时该属性也能从对应的对象上被删除
// enumerable:false,//值为 true 时,该属性才会出现在对象的枚举属性中
value:666,// 该属性对应的值
// writable:false,//值为 true 时,属性的值,也就是上面的 value,才能被赋值运算符改变
// get:()=>{},//当访问该属性时,会调用此函数。执行时不传入任何参数,但是会传入 this 对象(由于继承关系,这里的this并不一定是定义该属性的对象)。该函数的返回值会被用作属性的值
// set:()=>{},//当属性值被修改时,会调用此函数。该方法接受一个参数(也就是被赋予的新值),会传入赋值时的 this 对象。
})
三个参数
data
要定义的属性对象,这个很好理解
key
要定义或修改的属性的名称或 Symbol
1. key如果是原来就有的,修改后,还是数据属性,直接打印原对象里面可以看到这个属性
2. key如果是新增的,它就是访问器属性,直接打印原对象里面不可以看到这个属性
let obj = {
a: 1
}
Object.defineProperty(obj, 'a', { value: 2 })
Object.defineProperty(obj, 'b', { value: 3 })
console.log(obj)
console.log(obj.b)
obj 要定义或修改的属性描述符
里面的参数是固定的
Object.defineProperty(obj, 'a', {
// 这里面的参数是固定的
// configurable: false,//值为 true 时,该属性的描述符才能够被改变,同时该属性也能从对应的对象上被删除
// enumerable:false,//值为 true 时,该属性才会出现在对象的枚举属性中
value:666,// 该属性对应的值
// writable:false,//值为 true 时,属性的值,也就是上面的 value,才能被赋值运算符改变
// get:()=>{},//当访问该属性时,会调用此函数。执行时不传入任何参数,但是会传入 this 对象(由于继承关系,这里的this并不一定是定义该属性的对象)。该函数的返回值会被用作属性的值
// set:()=>{},//当属性值被修改时,会调用此函数。该方法接受一个参数(也就是被赋予的新值),会传入赋值时的 this 对象。
})
set和get方法使用
let obj = {
a: 1,
b: 1
}
// 尝试下get
Object.defineProperty(obj, 'a', {
get () {
console.log('---', obj)
return '666'
}
})
// 尝试下set
Object.defineProperty(obj, 'b', {
set (newValue) {
console.log('***', newValue)
return newValue + 1
}
})
console.log(obj.a)
obj.b = 90
obj.b = 100
console.log(obj);
value的使用
let obj = {
a: 1,
b: 1
}
Object.defineProperty(obj, 'a', {
value: 1000,
// get () {
// console.log(obj);
// },
// set (newVal) {
// console.log(newVal)
// }
})
console.log(obj.a)
console.log(obj)
注意value和set/get不能同时存在,会报错
let obj = {
a: 1,
b: 1
}
// 尝试下get
Object.defineProperty(obj, 'a', {
value: 1000,
get () {
console.log(obj);
},
set (newVal) {
console.log(newVal)
}
})
console.log(obj.a)
console.log(obj)
proxy
- 直译为代理,在我们访问对象前添加了一层拦截,可以过滤很多操作,例如对数据的处理,对构造函数的处理,对数据的验证等
语法
const p = new Proxy(target, handler)
参数
- target:要使用 Proxy 包装的目标对象(可以是任何类型的对象,包括原生数组,函数,甚至另一个代理)。
- handler:一个对象,其属性是当执行一个操作时定义代理的行为的函数(可以理解为某种触发器)
handler属性
- handler.get() 方法用于拦截对象的读取属性操作。
let obj = {
a: 1
}
// 参数一是需要处理的对象
// 参数二是对处理的对象的配置,参数是固定的
let test = new Proxy(obj, {
/**
* target目标对象
* property将被设置的属性名或 Symbol
* receiver最初被调用的对象
* target, property, receiver
* 目标,属性,接收者
*/
get (target, property, receiver) {
console.log('对obj做查询操作都会进来,这里做逻辑操作', target, property, receiver)
return 666 // 返回的值自由控制
}
})
console.log(test.a)
- handler.set() 方法用于拦截设置属性值的操作
注意,set方法需要返回一个布尔值
let obj = {
a: 1
}
// 参数一是需要处理的对象
// 参数二是对处理的对象的配置,参数是固定的
let test = new Proxy(obj, {
/**
* target目标对象
* property将被设置的属性名或 Symbol
* value新属性值
* receiver最初被调用的对象
* target, property, value, receiver
* 目标,属性,值,接收者
*/
set (target, property, value, receiver) {
console.log('对obj做修改操作都会进来,这里做逻辑操作', target, property, value, receiver)
target[property] = value // 将新属性值赋给目标对象
return true // set() 方法应当返回一个布尔值。
}
})
test.b = 666
console.log(test)
call方法
官网解释
调用一个对象的一个方法,以另一个对象替换当前对象
作用
-
继承
-
修改函数运行时this的指向
Reflect
官网解释
eflect 是一个内置的对象,它提供拦截 JavaScript 操作的方法。这些方法与proxy handlers的方法相同。Reflect不是一个函数对象,因此它是不可构造的。Reflect的所有属性和方法都是静态的(就像Math对象)。
静态方法
- get(),Reflect.get方法允许你从一个对象中取属性值。就如同属性访问器 语法,但却是通过函数调用来实现。
// 获取对象身上某个属性的值,类似于 target[name]。
// 返回值 属性的值
// 参数 目标对象 需要获取的值的键值 如果target对象中指定了getter,receiver则为getter调用时的this值。
Reflect.get(target, propertyKey[, receiver])
- set(),Reflect.set 方法允许你在对象上设置属性。它的作用是给属性赋值并且就像 property accessor 语法一样,但是它是以函数的方式。
// 在一个对象上设置一个属性。
// 返回值 返回一个 Boolean 值表明是否成功设置属性。
// 参数 目标对象 属性的名称 设置的值 如果遇到 setter,receiver则为setter调用时的this值。
Reflect.set(target, propertyKey, value[, receiver])
contain方法
- 判断当前dom是否包含另一个dom
A.contains(B) // 包含为true,不包含为false