首页 前端知识 Proxy 数据代理 对象操作的14种方法([[GetPrototypeOf]],[[SetPrototypeOf]],[[IsExtensible]]...)

Proxy 数据代理 对象操作的14种方法([[GetPrototypeOf]],[[SetPrototypeOf]],[[IsExtensible]]...)

2024-04-29 11:04:33 前端知识 前端哥 705 855 我要收藏

Proxy

数据代理
两个参数
let obj = new Proxy(target,handler)
target 目标对象 我们需要处理的对象
handler 容器 无数可以处理对象属性的方法
自定义获取对象属性的获取 赋值 枚举 函数调用等功能

var target = {
  a: 1,
  b: 2,
};
let proxy = new Proxy(target, {
  get(target, prop) {
    console.log('This is property value' + target[prop]);
  },
  set() {},
});

console.log(proxy.a);

在这里插入图片描述

var target = {
  a: 1,
  b: 2,
};
let proxy = new Proxy(target, {
  get(target, prop) {
    return 'This is property value' + target[prop];
  },
  set(target, prop, value) {
    target[prop] = value;
    console.log(target[prop]);
  },
});

console.log(proxy.a);
proxy.b = 3;

在这里插入图片描述

let target = {
  a: 1,
  b: 2,
};

let proxy = new Proxy(target, {
  get(target, prop) {
    return Reflect.get(target, prop);
  },
  set(target, prop, value) {
    target[prop] = value;
  },
  has(target, prop) {
    console.log(target[prop]);
  },
  deleteProperty(target, prop) {
    delete target[prop];
  },
});
console.log('a' in proxy);
console.log(proxy);

在这里插入图片描述

let target = {
  a: 1,
  b: 2,
};

let proxy = new Proxy(target, {
  get(target, prop) {
    return Reflect.get(target, prop);
  },
  set(target, prop, value) {
    target[prop] = value;
  },
  has(target, prop) {
    console.log(target[prop]);
  },
  deleteProperty(target, prop) {
    delete target[prop];
  },
});
delete proxy.b;
console.log(proxy);

在这里插入图片描述

操作数组

let arr = [
  { name: '小明', age: 18 },
  { name: '小红', age: 23 },
  { name: '小青', age: 14 },
  { name: '小黄', age: 35 },
  { name: '小王', age: 32 },
  { name: '小李', age: 40 },
];

let persons = new Proxy(arr, {
  age(arr, prop) {
    return arr[prop];
  },
  set(arr, prop, value) {
    arr[prop] = value;
  },
});
console.log(persons[3]);
persons[1] = { name: '小张', age: 33 };
console.log(persons);

在这里插入图片描述

操作函数

let fn = function () {
  console.log('I am a function');
};
fn.a = 123;

let newFn = new Proxy(fn, {
  get(fn, prop) {
    return fn[prop] + ' This is a Proxy return';
  },
});

console.log(newFn.a);

在这里插入图片描述
has不能拦截for in
has可以拦截in

let start = {
  a: 'lisi',
  b: 'zhangsan',
};

let agent = new Proxy(start, {
  has: function (target, key) {
    console.log('经过代理');
    if (key === 'a') {
      console.log('存在a');
      return target[key];
    }
  },
});

console.log('a' in agent);

在这里插入图片描述

let start = {
  a: 'lisi',
  b: 'zhangsan',
};

let agent = new Proxy(start, {
  has: function (target, key) {
    console.log('经过代理');
    if (key === 'a') {
      console.log('存在a');
      return target[key];
    }
  },
});

for (let key in agent) {
  console.log(agent[key]);
}

在这里插入图片描述

对象操作的14种方法

1.获取原型[[GetPrototypeOf]]

var obj = { a: 1, b: 2 };
var proto = Object.getPrototypeOf(obj);
console.log(proto);
console.log(obj.__proto__);
console.log(Object.prototype);

在这里插入图片描述

2.设置原型[[SetPrototypeOf]]

var obj = { a: 1, b: 2 };
Object.setPrototypeOf(obj, { c: 3, d: 4 });
console.log(obj);

在这里插入图片描述
或者通过 obj.proto= 去赋值

var obj = { a: 1, b: 2 };
// Object.setPrototypeOf(obj, { c: 3, d: 4 });
obj.__proto__ = { e: 5, f: 6 };
console.log(obj);

在这里插入图片描述

3.获取对象的可扩展性[[IsExtensible]]

返回一个布尔值

var obj = { a: 1, b: 2 };
var extensible = Object.isExtensible(obj);
console.log(extensible);

在这里插入图片描述
冻结后不可扩展

var obj = { a: 1, b: 2 };
var extensible = Object.isExtensible(obj);
console.log(extensible);

Object.freeze(obj);
var extensible2 = Object.isExtensible(obj);
console.log(extensible2);

在这里插入图片描述

Object.seal

封闭对象
不可修改
不可删除
可写
可读(可枚举)

var obj = { a: 1, b: 2 };
Object.seal(obj);
obj.c = 3;
console.log(obj);
delete obj.a;
console.log(obj);
obj.b = 3;
console.log(obj);
for (var key in obj) {
  console.log(obj[key]);
}

在这里插入图片描述

Object.freeze

冻结对象
不可修改
不可删除
不可写
可读(可枚举)

var obj = { a: 1, b: 2 };
Object.freeze(obj);
obj.c = 3;
console.log(obj);
delete obj.a;
console.log(obj);
obj.b = 3;
console.log(obj);
for (var key in obj) {
  console.log(obj[key]);
}

在这里插入图片描述

4.获取自有属性[[GetOwnProperty]]

var obj = { a: 1, b: 2 };
Object.setPrototypeOf(obj, { c: 3, d: 4 });
console.log(Object.getOwnPropertyNames(obj));

在这里插入图片描述

5.禁止扩展对象[[PreventExtensions]]

禁止增加属性

var obj = { a: 1, b: 2 };
Object.preventExtensions(obj);
obj.c = 3;
console.log(obj);

在这里插入图片描述
可删除属性

var obj = { a: 1, b: 2 };
Object.preventExtensions(obj);
obj.c = 3;
console.log(obj);
delete obj.a;
console.log(obj);

在这里插入图片描述

6.拦截对象操作[[DefineOwnProperty]]

Object.defineProperty
前文已经描述过

7.判断是否是自身属性[[HasOwnProperty]]

var obj = { a: 1, b: 2 };
console.log(obj.hasOwnProperty('a'));

在这里插入图片描述

8. [[Get]]

var obj = { a: 1, b: 2 };
console.log('a' in obj);
console.log(obj.a);

在这里插入图片描述

9. [[Set]]

var obj = { a: 1, b: 2 };
obj.a = 3;
obj['b'] = 4;
console.log(obj);

在这里插入图片描述

10.[[Delete]]

var obj = { a: 1, b: 2 };
delete obj.a;
console.log(obj);

在这里插入图片描述

11.枚举[[Enumerate]]

var obj = { a: 1, b: 2 };
for (var k in obj) {
  console.log(obj[k]);
}

在这里插入图片描述

12. 获取键集合 [[OwnPropertyKeys]]

var obj = { a: 1, b: 2 };
console.log(Object.keys(obj));

在这里插入图片描述

13.调用函数

var obj = { a: 1, b: 2 };
function test() {}
test();
test.call()
test.apply()
...
obj.test = function () {};
obj.test();

14.实例化的过程

function Test() {};
new Test(};

实现MyProxy

使用深拷贝与defineProperty实现一个简易的MyProxy

let target = {
  a: 1,
  b: 2,
};

function MyProxy(target, handler) {
  let _target = deepClone(target);
  Object.keys(_target).forEach((key) => {
    Object.defineProperty(_target, key, {
      get() {
        return handler.get && handler.get(target, key);
      },
      set(newValue) {
        handler.set && handler.set(target, key, newValue);
      },
    });
  });
  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;
  }
  return _target;
}

let proxy = new MyProxy(target, {
  get(target, prop) {
    return 'Get:' + prop + '=' + target[prop];
  },
  set(target, prop, value) {
    target[prop] = value;
    console.log('SET' + prop + '=' + value);
  },
});
console.log(proxy.a);
proxy.b = 4;
console.log(proxy.b);

在这里插入图片描述

Reflect

反射 方法的集合 全局下的对象 有对象操作的13种方法 除了枚举
Reflect.get Reflect.set 返回布尔值
在这里插入图片描述

转载请注明出处或者链接地址:https://www.qianduange.cn//article/6323.html
标签
评论
发布的文章

HTML5本地存储

2024-05-06 09:05:10

HTML5和CSS3新特性

2024-04-16 17:04:36

大家推荐的文章
会员中心 联系我 留言建议 回顶部
复制成功!