admin管理员组文章数量:1356319
My last question here: How to store data of a functional chain of Monoidal List?
had many great responses and one of them suggested to implement some sort of type structure in JavaScript:
const TYPE = Symbol();
const typeOf = t => x => x == null
? x
: Object.assign(x, {
[TYPE]: t
});
const isType = t => x => x == null
? false
: x[TYPE] === t;
const Foo = x => typeOf(Foo)(x);
console.log(
isType(Foo)(1) // false
, isType(Foo)([]) // false
, isType(Foo)({}) // false
, isType(Foo)(x => x) // false
, isType(Foo)(true) // false
, isType(Foo)(undefined) // false
, isType(Foo)(null) // false
);
console.log(
isType(Foo)(Foo(1)) // true
, isType(Foo)(Foo([])) // true
, isType(Foo)(Foo({})) // true
, isType(Foo)(Foo(x => x)) // true
, isType(Foo)(Foo(true)) // true
, isType(Foo)(Foo(undefined)) // false
, isType(Foo)(Foo(null)) // false
);
console.log(Foo(1) + Foo(2)); //3
My last question here: How to store data of a functional chain of Monoidal List?
had many great responses and one of them suggested to implement some sort of type structure in JavaScript:
const TYPE = Symbol();
const typeOf = t => x => x == null
? x
: Object.assign(x, {
[TYPE]: t
});
const isType = t => x => x == null
? false
: x[TYPE] === t;
const Foo = x => typeOf(Foo)(x);
console.log(
isType(Foo)(1) // false
, isType(Foo)([]) // false
, isType(Foo)({}) // false
, isType(Foo)(x => x) // false
, isType(Foo)(true) // false
, isType(Foo)(undefined) // false
, isType(Foo)(null) // false
);
console.log(
isType(Foo)(Foo(1)) // true
, isType(Foo)(Foo([])) // true
, isType(Foo)(Foo({})) // true
, isType(Foo)(Foo(x => x)) // true
, isType(Foo)(Foo(true)) // true
, isType(Foo)(Foo(undefined)) // false
, isType(Foo)(Foo(null)) // false
);
console.log(Foo(1) + Foo(2)); //3
While I thought this is a great idea, another member suggests this is inconsistent since Object.assign is a mutable operation and it should not be allowed in Functional Programming context.
In response, there is another idea to use Proxy instead, so I have tried to implement the similar system by myself.
The result is unfortunately very poor since Proxy
seems only to accept Object.
Works as the example
var target = {};
var p = new Proxy(target, {});
p.a = 37; // operation forwarded to the target
console.log(target.a); // 37. The operation has been properly forwarded
"Uncaught TypeError: Cannot create proxy with a non-object as target or handler"
var target = 5;
var p = new Proxy(target, {});
p.a = 37; // operation forwarded to the target
console.log(target.a); // 37. The operation has been properly forwarded
I also considered to take advantage of Object.create, but does not work in similar manner of Proxy
.
Basically, I recognise this is a challenge to implement Inheritance (object-oriented programming) in functional programming with dynamic typing/ duck typing and reflection.
Therefore, I really want to make this implementation work in ES6 Proxy context.
Any great ideas? Thanks.
Share Improve this question edited Jun 21, 2022 at 12:25 Morten 4,6077 gold badges31 silver badges31 bronze badges asked Jul 14, 2018 at 21:29 user6440264user6440264 3-
3
I think you have misunderstood what Proxy is. The whole point it to have functions in the second object to handle the "proxying" and of course the first argument has to be an object. Without it it will just pass whatever to the target and it will be mutated just as before. You can pass a new object as the first argument to
Object.assign
and then it will not mutate the original object. eg.Object.assign({}, x, { [TYPE]: t })
. In ES2018 you can do{ ...x, [TYPE]: t }
. – Sylwester Commented Jul 14, 2018 at 21:58 -
@Sylwester wow, this is not documented at all, and
{ ...x, ...y}
notation works in the current node.js enviroment. Thanks a lot ! – user6440264 Commented Jul 14, 2018 at 22:32 - @bayesian-study - Seems fairly well-documented to me. In the spec (here, which takes you here, which says "1. If Type(target) is not Object, throw a TypeError exception."), on MDN "target - A target object (can be any sort of object, including a native array, a function or even another proxy) to wrap with Proxy." – T.J. Crowder Commented Jul 15, 2018 at 8:10
1 Answer
Reset to default 5It turns out,
- Symbol()
- Object.assign()
- Proxy
all of them are not necessary to implement Reflection (puter programming) at least for this topic.
See my code below:
const selfAware = i => i[i] = i;
const isAware = i => (i[i] === i);
const I = i => (i === I) || (i == null)
? i
: selfAware(Object(i));
const amI = i => (i === I)
? true
: (i == null)
? false
: isAware(i);
const ss = I(6);
console.log(ss);
console.log(ss[ss]);
//self-similarity
console.log(ss[ss][ss]);
const obj1 = {
a: 2
};
const obj2 = I(obj1);
console.log(obj1);
console.log(obj2);
console.log(
I("Hello world!").toString() //Yes, it works!
);
console.log(I(1) + I(2)); //3
console.log(
(I) //[Function: I]
);
console.log(
(I)(I) //[Function: I]
);
console.log(
(I)(I)(I) //[Function: I]
);
console.log(
(I)(I)(I)(I) //[Function: I]
);
console.log("============================");
console.log(
amI(I) //true
, amI(1) // false
, amI([]) // false
, amI({}) // false
, amI(x => x) // false
, amI(true) // false
, amI(false) // false
, amI(undefined) // false
, amI(null) // false
);
console.log(
amI(I(I)) // true
, amI(I(1)) // true
, amI(I([])) // true
, amI(I({})) // true
, amI(I(x => x)) // true
, amI(I(true)) // true
, amI(I(false)) // true
, amI(I(undefined)) // false
, amI(I(null)) // false
);
本文标签:
版权声明:本文标题:javascript - ES6 proxy work-around for "TypeError: Cannot create proxy with a non-object as target"? - Stack O 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1744056311a2583318.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论