(1).defineproperties
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 Calculator extends Compute{
constructor(doc){
super();
const oCal = doc.getElementsByClassName('J_calculator')[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];
this.data = this.defineData();
this.btnIdx = 0;
}
init(){
this.bindEvent();
}
bindEvent(){
this.oBtnGroup.addEventListener('click',this.onFieldBtnClick.bind(this));
this.fInput.addEventListener('input',this.onNumberInput.bind(this));
this.sInput.addEventListener('input',this.onNumberInput.bind(this));
}
defineData(){
let _obj = {},
fNumber = 0,
sNumber = 0,
field = 'plus';
const _self = this;
Object.defineProperties(_obj,{
fNumber:{
get(){
return fNumber;
},
set(newValue){
fNumber = newValue;
_self.computeResult(fNumber,sNumber,field);
}
},
sNumber:{
get(){
return sNumber;
},
set(newValue){
sNumber = newValue;
_self.computeResult(fNumber,sNumber,field);
}
},
field:{
get(){
return field;
},
set(newValue){
field = newValue;
_self.computeResult(fNumber,sNumber,field);
}
}
})
return _obj
}
onFieldBtnClick(ev){
const e = ev || window.event,
tar = e.target || e.srcElement,
tagName = tar.tagName.toLowerCase();
tagName === 'button' && this.fieldUpdate(tar)
}
fieldUpdate(target){
this.oBtnItems[this.btnIdx].className = '';
this.btnIdx = [].indexOf.call(this.oBtnItems,target);
target.className += ' current';
this.data.field = target.getAttribute('data-field');
}
onNumberInput(ev){
const e = ev || window.event,
tar = e.target || e.srcElement,
className = tar.className,
val = Number(tar.value.replace(/\s+/g,'')) || 0;
switch(className){
case 'f-input':
this.data.fNumber = val;
break;
case 's-input':
this.data.sNumber = val;
break;
}
}
computeResult(fNumber,sNumber,field){
this.oResult.innerText = this[field](fNumber,sNumber);
}
}
new Calculator(document).init()
(2).proxy
并不是数据劫持,而是代理,是自定义对象属性的获取、赋值、枚举、函数调用等功能
1.使用形式
函数
let fn = function(){
console.log('我是function');
}
fn.a = 123
let newFn = new Proxy(fn,{
get(fn,prop){
return fn[prop]+'proxy return'
}
})
console.log(newFn.a);// 123proxy return
对象
let target = {
a:1,
b:2
}
let proxy = new Proxy(target,{
get(target,prop){
return 'proxy'+target[prop];
},
set(target,prop,value){
target[prop] = value;
console.log(target[prop]);
}
})
console.log(proxy.a);//proxy 1
console.log(target.a); 1
proxy.b = 3
console.log(target.b);3 更改代理也会影响原数据
2.操作对象的14种方法
var obj = {a:1,b:2}
1.获取原型[[GetPrototypeOf]]
var proto = Object.getPrototypeOf(obj)
2.设置原型[[SetPrototypeOf]]
Object.setPrototypeOf(obj,{c:3,d:4})
3.获取对象的可扩展性[[IsExtensible]]
let ext = Object.isExtensible(obj)
console.log(ext)
Object.freeze(obj);true
let ext2 = Object.isExtensible(obj)
console.log(ext2);false
封闭对象=seal 不可增加 不可删除 可修改 可读
冻结对象=freeze 不可增加 不可删除 不可修改 可读
4.获取自有属性[[GetOwnProperty]]
Object.setPrototypeOf(obj,{c:3,d:4});
console.log(Object.getOwnPropertyNames(obj))a b
5.禁止扩展对象
Object.preventExtensions(obj);
obj.c = 3;
console.log(obj)//1 2 没有3 是可删除的
6.拦截对象操作[[DefineOwnProperty]]
Object.defineProperty()
7.判断是否是自身属性[[HasProperty]]
console.log(obj.hasOwnProperty('a'));
8.[[GET]]
console.log(obj.a)
9.[[SET]]
obj.a=3
obj['a']=3
10.[[Delete]]
delete obj.a
console.log(obj)
11.[[Enumerate]]
for (var k in obj){
console.log(obj[k])
}
12.获取键集合[[OwnPropertyKeys]]
console.log(Object.keys(obj));
13.函数调用执行
function test(){} test();
obj.test = function(){} obj.test()
14.实例化
function Test(){} new Test();
(3).重写
function MyProxy(target,handler){
let _target = deepClone(target);
function deepClone(org,tar){
var tar = tar || {},
toStr = Object.prototype.toString,
arrType = '[object Array]';
for(var key in org){
if(org.hasOwnProperty(key)){
if(typeof(org[key]) === 'object' && org[key] !== null){
tar[key] = toStr.call(org[key]) === arrType ? [] : {}
deepClone(org[key],tar[key]);
}else{
tar[key] = org[key]
}
}
}
return tar;
}
Object.keys(_target).forEach((key)=>{
Object.defineProperty(_target,key,{
get(){
return handler.get && handler.get(target,key)
},
set(newVal){
handler.set && handler.set(target,key,newVal)
}
})
})
return _target;
}
(4).proxy还可以写其他方法
let target = {
a:1,
b:2
}
let proxy = new Proxy(target,{
get(target,prop){
return 'proxy'+target[prop];
},
set(target,prop,value){
target[prop] = value;
// console.log(target[prop]);
},
has(target,prop){
console.log(1111)
console.log(target[prop])
},
deleteProperty(target,prop){
delete target[prop];
console.log(1)
}
})
delete proxy.b;
console.log('a' in proxy) 打印1 111 1 false
(5).reflect
14中方法除去枚举都放到了reflect上,好处是可以返回状态
let target = {
a:1,
b:2
}
let proxy = new Proxy(target,{
get(target,prop){
return Reflect.get(target,prop)
},
set(target,prop,value){
const isOk = Reflect.set(target,prop,value);
if(isOk){
console.log(target[prop]);
}
}
})