defineProperty属性的理解与使用

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()
  • 7
    点赞
  • 46
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值