ECMAScript 6 proxies
2016-01-28 13:46
435 查看
在ECMAScript 5里面,可以通过(writable 和 configurable)内部属性把属性设置为不可修改和不可删除的,可以通过(Object.preventExtensions() )让对象不允许被拓展新的属性,可以通过(Object.freeze())让对象的所有属性变为只读和不可删除的,同时也不能添加新属性,或者(Object.seal() )等。
"use strict";
var person = {
name: "Nicholas"
};
Object.seal(person);
person.age = 20; // Error!
上面的代码会触发错误,因为对象被密封了,不允许添加新属性
但是在非strict模式下,不会出现错误提示,即使属性无法添加,也不会有任何提示(通常访问不存在的对象属性只会返回undefined),这就会在调试上带来麻烦
当读从对象读取一个属性值的时候,会触发一个内部的[[Get]]操作来获取属性值,这是一个内部的不可改变的行为,但是通过 proxies 可以拦截javascript engine对[[Get]]的调用,转而调用自定义的函数
var proxy = new Proxy({ name: "Nicholas" }, {
get: function(target, property) {
if (property in target) {
return target[property];
} else {
return 35;
}
}
});
console.log(proxy.time); // 35
console.log(proxy.name); // "Nicholas"
console.log(proxy.title); // 35
改造一下便可以成为一个让对象不存在属性被访问时触发错误的函数
function createDefensiveObject(target) {
return new Proxy(target, {
get: function(target, property) {
if (property in target) {
return target[property];
} else {
throw new ReferenceError("Property \"" + property + "\" does not exist.");
}
}
});
}
使用方式:
var person = {
name: "Nicholas"
};
var defensivePerson = createDefensiveObject(person);
console.log(defensivePerson.name); // "Nicholas"
console.log(defensivePerson.age); // Error!
其他常规操作不受影响
defensivePerson.age = 13;
console.log(defensivePerson.age); // 13
console.log("name" in defensivePerson); // true
console.log(defensivePerson.hasOwnProperty("name")); // true
通过对设置内部[[Set]],可以让属性添加的时候判断类型
function createTypeSafeObject(object) {
return new Proxy(object, {
set: function(target, property, value) {
var currentType = typeof target[property],
newType = typeof value;
if (property in target && currentType !== newType) {
throw new Error("Property " + property + " must be a " + currentType + ".");
} else {
target[property] = value;
}
}
});
}
上面两个方法都可以安全用到构造函数里面,因为proxies是透明的,不影响其他代码
function Person(name) {
this.name = name;
return createTypeSafeObject(this);
}
var person = new Person("Nicholas");
console.log(person instanceof Person); // true
console.log(person.name); // "Nicholas"
"use strict";
var person = {
name: "Nicholas"
};
Object.seal(person);
person.age = 20; // Error!
上面的代码会触发错误,因为对象被密封了,不允许添加新属性
但是在非strict模式下,不会出现错误提示,即使属性无法添加,也不会有任何提示(通常访问不存在的对象属性只会返回undefined),这就会在调试上带来麻烦
当读从对象读取一个属性值的时候,会触发一个内部的[[Get]]操作来获取属性值,这是一个内部的不可改变的行为,但是通过 proxies 可以拦截javascript engine对[[Get]]的调用,转而调用自定义的函数
var proxy = new Proxy({ name: "Nicholas" }, {
get: function(target, property) {
if (property in target) {
return target[property];
} else {
return 35;
}
}
});
console.log(proxy.time); // 35
console.log(proxy.name); // "Nicholas"
console.log(proxy.title); // 35
改造一下便可以成为一个让对象不存在属性被访问时触发错误的函数
function createDefensiveObject(target) {
return new Proxy(target, {
get: function(target, property) {
if (property in target) {
return target[property];
} else {
throw new ReferenceError("Property \"" + property + "\" does not exist.");
}
}
});
}
使用方式:
var person = {
name: "Nicholas"
};
var defensivePerson = createDefensiveObject(person);
console.log(defensivePerson.name); // "Nicholas"
console.log(defensivePerson.age); // Error!
其他常规操作不受影响
defensivePerson.age = 13;
console.log(defensivePerson.age); // 13
console.log("name" in defensivePerson); // true
console.log(defensivePerson.hasOwnProperty("name")); // true
通过对设置内部[[Set]],可以让属性添加的时候判断类型
function createTypeSafeObject(object) {
return new Proxy(object, {
set: function(target, property, value) {
var currentType = typeof target[property],
newType = typeof value;
if (property in target && currentType !== newType) {
throw new Error("Property " + property + " must be a " + currentType + ".");
} else {
target[property] = value;
}
}
});
}
上面两个方法都可以安全用到构造函数里面,因为proxies是透明的,不影响其他代码
function Person(name) {
this.name = name;
return createTypeSafeObject(this);
}
var person = new Person("Nicholas");
console.log(person instanceof Person); // true
console.log(person.name); // "Nicholas"
相关文章推荐
- 常见 Java 字节码 指令 助记符
- delphi非常简单的线程安全队列
- C++的sstream相关知识
- 淘宝Tprofiler工具实现分析
- Android平台使用MediaCodec进行H264格式的视频编解码
- Java中的get()和set()方法
- Datatable的Select()方法简介
- 大小不固定 文字图片居中
- Git 忽略一些文件不加入版本控制
- 在Linux下的进程资源的限制(struct rlimit)详解
- Anroid中两台手机连接同一wifi通过socket进行通信
- css怎么写
- 以 Console 方式运行、调试、编译 .Net 编写的 Windows 服务
- Javascript面向对象编程(三):非构造函数的继承
- JAVA基础----java中E,T,?的区别?
- 常见的项目文件介绍
- Leetcoed 277 Find the Celebrity
- 编译VTK时Qt5_DIR-NOTFOUND的解决方法
- HttpClient中头部Header用法
- Android自定View——可以设置宽高比例的ImageView