Object.defineProperty这个方法用于给对象添加属性或者修改已有属性的的值。
该方法接收三个参数:
1.要添加或者修改属性的所在对象
2.要添加或者修改的属性名称
3.要添加或者修改的属性描述符
// Object.defineProperty入参演示
const obj={};
Object.defineProperty(obj,'name',{})
属性描述符是个什么东西呢?它可以是数据属性,也可以是访问器属性:
作为数据属性,它有四个配置参数:
value:控制属性的默认值,默认为undefined;
enumerable:控制属性是否可以枚举,默认为false;
writable:控制属性是否可以被修改,默认为false;
configurable:控制属性是否可以被删除,默认为false;
tip:
通过数据属性创建的时候,其数据属性默认值为false,但是直接通过对象量创建的时候const a={name:‘baidu’},其数据属性默认为true
// Object.defineProperty属性描述符-数据属性演示
const obj={};
Object.defineProperty(obj,'name',{
value:'baidu',
enumerable:false,
writable:false,
configurable:false
})
作为访问器属性:
get:function(){} :在读取属性时调用的函数,必须return一个值,默认值是undefined
set:function(value){} :在设置属性时调用的函数,value为当前设置的值
// Object.defineProperty属性描述符-访问器属性演示
const obj={};
let n=undefined;
Object.defineProperty(obj,'name',{
set:function(value){
console.log('有人设置了obj.name:',value)
n=value
},
get:function(){
console.log('有人获取了obj.name',n)
return n
}
})
Object.defineProperty仅用于单个属性的添加或者修改,如果想要定义多个属性,则可以使用Object.defineProperties来同时来定义多个属性:
// Object.defineProperty属性描述符-访问器属性演示
const obj={};
let n=undefined;
Object.defineProperties(obj,{
name:{
value:'baidu',
configurable:false
},
age:{
get:function(){
return n
},
set:function(value){
n=value
}
}
})
Object.defineProperty这个方法其实也是vue实现数据劫持的核心方法,用来实现双向绑定,以下是一个简单的双向绑定的例子:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>双向绑定范例</title>
</head>
<style>
#test-input {
margin-bottom: 10px;
}
#test-view {
width: 200px;
height: 200px;
border: 1px solid red;
}
</style>
<body>
<input id="test-input" type="input" />
<div id="test-view"></div>
<script>
const inputDom = document.getElementById("test-input");
const viewDom = document.getElementById("test-view");
window.testData = {};
let input_value = undefined;
inputDom.addEventListener("input", function (e) {
const changeValue = e.target.value;
console.log("输入框变化:", changeValue);
window.testData.inputValue = changeValue;
});
inputDom.addEventListener("blur", function () {
console.log(window.testData.inputValue, "==");
});
Object.defineProperty(window.testData, "inputValue", {
get: function () {
console.log("获取到window.testData.inputValue的值:", input_value);
return input_value;
},
set: function (changeValue) {
input_value = changeValue;
viewDom.innerText = changeValue;
},
});
</script>
</body>
</html>
最终效果: