Skip to content
This repository was archived by the owner on Sep 8, 2024. It is now read-only.

Commit 58df702

Browse files
authored
update to v1.2.0
1. add `Proxy.revocable` method 2. add a test case
1 parent 383e948 commit 58df702

File tree

10 files changed

+122
-31
lines changed

10 files changed

+122
-31
lines changed

README.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ Due to the limitations of ES3, the polyfill supports just a limited number of pr
99
* apply
1010
* construct
1111

12+
The `Proxy.revocable` method is also supported, but only for calls to the above traps.
1213

1314
#### Installation
1415

@@ -44,4 +45,5 @@ var proxy = new Proxy(target, handler);
4445
<script src="path/to/babel-polyfill.js" type="text/javascript"></script>
4546
<script src="path/to/es6-proxy-polyfill.js" type="text/javascript"></script>
4647
```
47-
2. The code has been tested on Node.js 0.10.48 and IE8, and it may work in other environments too.
48+
2. The code has been tested on Node.js 0.10.48 and IE8, and it may work in other environments too;
49+
3. The revoked `Proxy` object will not throw errors when it's properties are accessed.

README_zh.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
* apply
1010
* construct
1111

12+
`Proxy.revocable`方法也被支持,但只限于调用上面的'traps'。
1213

1314
#### 安装
1415

@@ -44,4 +45,5 @@ var proxy = new Proxy(target, handler);
4445
<script src="path/to/babel-polyfill.js" type="text/javascript"></script>
4546
<script src="path/to/es6-proxy-polyfill.js" type="text/javascript"></script>
4647
```
47-
2. 代码已经在Node.js 0.10.48 和 IE8 测试过,而且它也应该能够运行在其他环境下。
48+
2. 代码已经在Node.js 0.10.48 和 IE8 测试过,而且它也应该能够运行在其他环境下;
49+
3. 当自身属性被访问时,被撤销的`Proxy`对象不会抛出错误。

dist/es6-proxy-polyfill.js

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/es6-proxy-polyfill.js.map

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,17 @@
11
{
22
"name": "es6-proxy-polyfill",
3-
"version": "1.0.0",
3+
"version": "1.2.0",
44
"description": "Proxy polyfill based on ES3 supports IE8, Node.js, etc.",
55
"main": "src/es6-proxy-polyfill.js",
66
"scripts": {
77
"build": "uglifyjs src/es6-proxy-polyfill.js -c -m reserved=[Proxy] --ie8 --comments --source-map -o dist/es6-proxy-polyfill.js"
88
},
99
"keywords": [
10+
"es6-proxy",
1011
"proxy-polyfill",
1112
"proxy",
1213
"polyfill",
13-
"ie8",
14-
"es6"
14+
"ie8"
1515
],
1616
"author": "[email protected]",
1717
"license": "Apache-2.0",

src/es6-proxy-polyfill.js

Lines changed: 33 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/**
22
* ES6 Proxy Polyfill
3-
* @version 1.0.0
3+
* @version 1.2.0
44
* @author Ambit Tsai <[email protected]>
55
* @license Apache-2.0
66
* @see {@link https://github.com/ambit-tsai/es6-proxy-polyfill}
@@ -67,11 +67,7 @@
6767
}
6868
if(handler.construct == null){
6969
obj = target.apply(thisArg, argsList);
70-
if(obj instanceof Object){
71-
return obj;
72-
}else{
73-
return thisArg;
74-
}
70+
return obj instanceof Object? obj: thisArg;
7571
}else if(typeof handler.construct === 'function'){
7672
obj = handler.construct(target, argsList);
7773
if(obj instanceof Object){
@@ -88,9 +84,10 @@
8884
* Create a Proxy object
8985
* @param {Function} target
9086
* @param {Object} handler
87+
* @param {Object} result
9188
* @returns {Function}
9289
*/
93-
function createProxy(target, handler){
90+
function createProxy(target, handler, result){
9491
// Check the type of arguments
9592
if(typeof target !== 'function'){
9693
throwTypeError('Proxy polyfill only support function target');
@@ -112,6 +109,17 @@
112109
P.prototype = target.prototype; // copy target's prototype
113110
setProto(P, getProto(target)); // copy target's [[Prototype]]
114111

112+
// The Proxy revocation function
113+
result && (result.revoke = function(){
114+
member.target = null;
115+
member.handler = null;
116+
for(var key in P){ // delete proxy's properties
117+
P.hasOwnProperty(key) && delete P[key];
118+
}
119+
P.prototype = {}; // reset proxy's prototype
120+
setProto(P, {}); // reset proxy's [[Prototype]]
121+
});
122+
115123
return P;
116124
}
117125

@@ -129,11 +137,23 @@
129137
throwTypeError("Constructor Proxy requires 'new'");
130138
}
131139
}
132-
133-
// Prevent function declaration from being translated into function expression by UglifyJS.
134-
// Function expression called by 'new' will cause an inconsistent result between old IE and
135-
// others when runing the code - `this instanceof P`.
136-
Proxy.revocable;
140+
141+
/**
142+
* Create a revocable Proxy object
143+
* @param {Function} target
144+
* @param {Object} handler
145+
* @returns {{proxy, revoke}}
146+
*/
147+
Proxy.revocable = function(target, handler){
148+
var result = {};
149+
result.proxy = createProxy(target, handler, result);
150+
return result;
151+
};
137152

138153
global.Proxy = Proxy;
139-
}(typeof window==='object'? window: global));
154+
}(
155+
typeof window === 'object'?
156+
window:
157+
// Using `this` for web workers & supports Browserify / Webpack.
158+
typeof global==='object'? global: this
159+
));

test/browser/proxy-revocable.html

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
<!DOCTYPE html>
2+
<html>
3+
<head>
4+
<meta http-equiv="content-type" content="text/html;charset=utf-8">
5+
<title>proxy-revocable</title>
6+
</head>
7+
<body>
8+
<script src="../../dist/es6-proxy-polyfill.js" type="text/javascript"></script>
9+
<script type="text/javascript">
10+
var person = {
11+
name: "Ambit_Tsai",
12+
sayHello: function(){
13+
document.write(">"+this.name+": Hey man!<br>");
14+
}
15+
};
16+
17+
var result = Proxy.revocable(person.sayHello, {
18+
apply: function(func, ctx, args){
19+
document.write("Trigger 'apply' trap<br>");
20+
func.apply(ctx, args);
21+
}
22+
});
23+
person.sayHello = result.proxy;
24+
25+
document.write("Call 'sayHello' method<br>");
26+
person.sayHello();
27+
28+
document.write("Revoke proxy<br>");
29+
result.revoke();
30+
31+
try{
32+
document.write("Call 'sayHello' method again<br>");
33+
person.sayHello();
34+
}catch(err){
35+
document.write(err.message+"<br>");
36+
}
37+
</script>
38+
</body>
39+
</html>

test/browser/trap-construct.html

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,25 +8,25 @@
88
<script src="../../dist/es6-proxy-polyfill.js" type="text/javascript"></script>
99
<script type="text/javascript">
1010
function Person(name){
11-
document.write("Set this.name to '"+name+"'<br>");
11+
document.write("Property 'name' is initialized to '"+name+"'<br>");
1212
this.name = name;
1313
}
1414
Person.prototype.sayHello = function(){
1515
document.write(">"+this.name+": Hey man!<br>");
1616
};
1717
Person.className = "Person";
1818

19-
var NewPerson = new Proxy(Person, {
19+
var ProxyClass = new Proxy(Person, {
2020
construct: function(Target, args){
2121
document.write("Trigger 'construct' trap<br>");
2222
return new Target(args[0]);
2323
}
2424
});
2525

26-
document.write("NewPerson's className: '"+NewPerson.className+"' (need 'Object.assign')<br>");
26+
document.write("ProxyClass's className: '"+ProxyClass.className+"' (Rely on 'Object.assign')<br>");
2727

28-
document.write("Create a NewPerson object<br>");
29-
var person = new NewPerson("Ambit_Tsai");
28+
document.write("Create a ProxyClass object<br>");
29+
var person = new ProxyClass("Ambit_Tsai");
3030

3131
document.write("Call 'sayHello' method<br>");
3232
person.sayHello();

test/nodejs/proxy-revocable.js

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
require('../../dist/es6-proxy-polyfill');
2+
3+
var person = {
4+
name: "Ambit_Tsai",
5+
sayHello: function(){
6+
console.log(">"+this.name+": Hey man!");
7+
}
8+
};
9+
var result = Proxy.revocable(person.sayHello, {
10+
apply: function(func, ctx, args){
11+
console.log("Trigger 'apply' trap");
12+
func.apply(ctx, args);
13+
}
14+
});
15+
person.sayHello = result.proxy;
16+
17+
console.log("Call 'sayHello' method");
18+
person.sayHello();
19+
20+
console.log("Revoke proxy");
21+
result.revoke();
22+
23+
try{
24+
console.log("Call 'sayHello' method again");
25+
person.sayHello();
26+
}catch(err){
27+
console.log(err.message);
28+
}

test/nodejs/trap-construct.js

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,25 @@
11
require('../../src/es6-proxy-polyfill');
22

33
function Person(name){
4-
console.log("Set this.name to '"+name+"'");
4+
console.log("Property 'name' is initialized to '"+name+"'");
55
this.name = name;
66
}
77
Person.prototype.sayHello = function(){
88
console.log(">"+this.name+": Hey man!");
99
};
1010
Person.className = "Person";
1111

12-
var NewPerson = new Proxy(Person, {
12+
var ProxyClass = new Proxy(Person, {
1313
construct: function(Target, args){
1414
console.log("Trigger 'construct' trap");
1515
return new Target(args[0]);
1616
}
1717
});
1818

19-
console.log("NewPerson's className: '"+NewPerson.className+"' (need 'Object.assign')");
19+
console.log("ProxyClass's className: '"+ProxyClass.className+"' (Rely on 'Object.assign')");
2020

21-
console.log("Create a NewPerson object");
22-
var person = new NewPerson("Ambit_Tsai");
21+
console.log("Create a ProxyClass object");
22+
var person = new ProxyClass("Ambit_Tsai");
2323

2424
console.log("Call 'sayHello' method");
2525
person.sayHello();

0 commit comments

Comments
 (0)