defineProperty的参数
defineProperty(obj,prop,desc)
第一个参数为需要定义属性的对象
第二个参数为需要定义的属性名
第三个参数为属性描述符
var obj={}
//为obj对象添加name属性,值为lisa
Object.defineProperty(obj,"name",{
value:"lisa"
})
console.log(obj) //{name:'lisa'}
//为obj对象同时添加多个属性
Object.defineProperties(obj,{
age:{value:11},
class:{value:12}
})
console.log(obj) //{name: "lisa", age: 11, class: 12}
使用definePropery定义的属性不能对其进行修改,删除,以及枚举。
怎么解决呢?
在属性描述符中设置
writable:true 可修改
enumerable:true 可枚举
configurable:true 可操作/删除
var obj={}
Object.defineProperty(obj,"name",{
value:"lisa",
writable:true,
enumerable:true,
configurable:true
})
defineProperty的set和get属性
用于实现数据劫持
var obj={}
var a=1;
Object.defineProperties(obj,{
a:{
// 注意:value,writable属性与get,set互斥,如果同时存在则会报错
//所以,设置初始值只能在外部设置
//在a被访问时返回a的值
get(){
console.log("a被访问了,值为"+a)
return a;
},
//在a被修改时,将a的值修改为传入的新值
set(newVal){
a=newVal;
console.log("a被修改了,值为"+a)
}
}
})
obj.a //访问a,值为1
obj.a=5 //设置a的值,值为5
obj.a//再次访问a,值为5
利用defineProperty来操作数组
function DataArr(){
var Arrobj={} //数组的属性
var arr=[]
//this指向new DataArr()
Object.defineProperty(this,"val",{
get(){
return Arrobj;
},
set(newVal){
Arrobj=newVal
//向数组中添加新的属性值
arr.push({val:Arrobj})
}
})
this.getArr=function(){
return arr
}
}
var dataArr=new DataArr()
dataArr.val=123
dataArr.val=456
console.log(dataArr.getArr()) //[{val:123},{val:456}]
计算器
<style type="text/css">
.btn-group button.current{background-color: aqua;}
</style>
<div class="calculater">
<div class="result">0</div>
<div class="inputgroup">
<input type="text" value="0" class="f-input">
<input type="text" value="0" class="s-input">
</div>
<div class="btn-group">
<button data-field="plus" class="current" >+</button>
<button data-field="minus" >-</button>
<button data-field="mul" >*</button>
<button data-field="div" >/</button>
</div>
</div>
class Compute{
plus(a,b){
return a+b
}
minus(a,b){
return a-b
}
mul(a,b){
return a*b
}
div(a,b){
return a/b
}
}
class Calculater extends Compute{
constructor(doc) {
super();//继承构造器
const oCal = doc.getElementsByClassName("calculater")[0]
this.fInput = oCal.getElementsByTagName("input")[0]
this.sInput = oCal.getElementsByTagName("input")[1]
this.oBtnGroup = oCal.getElementsByClassName("btn-group")[0]
this.oBtnItems = this.oBtnGroup.getElementsByTagName("button")
this.oResult = oCal.getElementsByClassName("result")[0]
//为数据添加get,set属性
this.data = this.defineData()
this.btnIndex = 0
console.log(this.data)
}
//初始化操作
init() {
//绑定点击事件
this.bindEvent()
}
bindEvent() {
//为oBtnGroup添加click事件并改变this指向
this.oBtnGroup.addEventListener('click', this.onFieldBtnClick.bind(this), false);
this.fInput.addEventListener('input',this.onNumberInput.bind(this),false)
this.sInput.addEventListener('input',this.onNumberInput.bind(this),false)
}
defineData() {
var obj = {};
var fNumber = 0;
var sNumber = 0;
var field = "plus"
var _self=this
Object.defineProperties(obj, {
fNumber: {
get() {
console.log("fNumber被访问")
return fNumber
},
set(newVal) {
fNumber = newVal
_self.computeResult(fNumber,sNumber,field)
console.log("fNumber被修改")
}
},
sNumber: {
get() {
console.log("sNumber被访问")
return sNumber
},
set(newVal) {
sNumber = newVal
_self.computeResult(fNumber,sNumber,field)
console.log("sNumber被修改")
}
},
field: {
get() {
console.log("field被访问")
return field
},
set(newVal) {
field = newVal
_self.computeResult(fNumber,sNumber,field)
console.log("field被修改")
}
}
})
return obj
}
onFieldBtnClick(ev){
var e = ev || window.event
var target = e.target ||e.srcElement
var tagName=target.tagName.toLowerCase()
tagName =="button" && this.fieldUpdate(target)
}
fieldUpdate(target){
//将样式置为空
this.oBtnItems[this.btnIndex].className="";
//获取当前的index
this.btnIndex=[].indexOf.call(this.oBtnItems,target)
//为当前btn添加样式
target.className+="current"
this.data.field=target.getAttribute("data-field")
}
onNumberInput(ev){
var e = ev || window.event
var target = e.target ||e.srcElement
//获取input的值
var val=Number(target.value.replace(/\s+/g,"")) || 0
var className=target.className
switch(className){
case "f-input":
this.data.fNumber=val
break;
case "s-input":
this.data.sNumber=val
break;
default:
break;
}
}
computeResult(fNumber,sNumber,field){
this.oResult.innerHTML=this[field](fNumber,sNumber)//不太懂
}
}
new Calculater(document).init()