- xml - AJAX/Jquery XML 解析
- 具有多重继承的 XML 模式
- .net - 枚举序列化 Json 与 XML
- XML 简单类型、简单内容、复杂类型、复杂内容
我试图完成的事情。我想共享一个 Canvas (因为我正在做的事情很重)所以我想我会做一个有限的资源管理器。您会通过 promise 向它请求资源,在本例中为 Canvas2DRenderingContext
。它将上下文包装在一个可撤销的代理中。完成后,您需要调用 release,这既会将 Canvas 返回给有限的资源管理器,这样它就可以将它交给其他人,并且它会撤销代理,这样用户就不会意外地再次使用该资源。
除非我制作 Canvas2DRenderingContext
的代理失败。
const ctx = document.createElement('canvas').getContext('2d');
const proxy = new Proxy(ctx, {});
// try to change the width of the canvas via the proxy
test(() => { proxy.canvas.width = 100; }); // ERROR
// try to translate the origin of via the proxy
test(() => { proxy.translate(1, 2); }); // ERROR
function test(fn) {
try {
fn();
} catch (e) {
console.log("FAILED:", e, fn);
}
}
上面的代码在 Chrome 中生成 Uncaught TypeError: Illegal invocation
,在 Firefox 中生成 TypeError: 'get canvas' called on an object that does not implement interface CanvasRenderingContext2D.
这是 Proxy 的预期限制还是错误?
注意:当然还有其他解决方案。我可以删除代理而不用担心它。我还可以将 Canvas 包裹在一些 JavaScript 对象中,这些对象只公开我需要的功能并代理它。我只是更好奇这是否应该起作用。 This Mozilla blog post kind of indirectly suggests it's supposed to be possbile 因为它实际上提到使用带有 HTMLElement
的代理如果只是指出如果你调用 someElement.appendChild(proxiedElement)
它肯定会失败但考虑到上面的简单代码我希望它实际上不可能有意义地包装任何 DOM 元素或其他 native 对象。
下面是代理与普通 JS 对象一起工作的证明。他们基于类工作(因为函数在原型(prototype)链上)。而且它们不适用于 native 对象。
const img = document.createElement('img')
const proxy = new Proxy(img, {});
console.log(proxy.src);
同样的错误也失败了。他们不使用 JavaScript 对象的地方
function testNoOpProxy(obj, msg) {
log(msg, '------');
const proxy = new Proxy(obj, {});
check("get property:", () => proxy.width);
check("set property:", () => proxy.width = 456);
check("get property:", () => proxy.width);
check("call fn on object:", () => proxy.getContext('2d'));
}
function check(msg, fn) {
let success = true;
let r;
try {
r = fn();
} catch (e) {
success = false;
}
log(' ', success ? "pass" : "FAIL", msg, r, fn);
}
const test = {
width: 123,
getContext: function() {
return "test";
},
};
class Test {
constructor() {
this.width = 123;
}
getContext() {
return `Test width = ${this.width}`;
}
}
const testInst = new Test();
const canvas = document.createElement('canvas');
testNoOpProxy(test, 'plain object');
testNoOpProxy(testInst, 'class object');
testNoOpProxy(canvas, 'native object');
function log(...args) {
const elem = document.createElement('pre');
elem.textContent = [...args].join(' ');
document.body.appendChild(elem);
}
pre { margin: 0; }
嗯,FWIW,我选择的解决方案是将 Canvas 包装在一个小类中,该小类可以完成我使用它的目的。优点是它更容易测试(因为我可以传入模拟)并且我可以毫无问题地代理该对象。不过还是想知道
最佳答案
const handlers = {
get: (target, key) => key in target ? target[key] : undefined,
set: (target, key, value) => {
if (key in target) {
target[key] = value;
}
return value;
}
};
const { revoke, proxy } = Proxy.revocable(ctx, handlers);
// elsewhere
try {
proxy.canvas.width = 500;
} catch (e) { console.log("Access has been revoked", e); }
类似的东西应该可以满足您的期望。
一个可撤销的代理,带有获取和设置陷阱的处理程序,用于上下文。
请记住,当 Proxy.revocable()
的实例被撤销时,该代理的任何后续访问都将抛出异常,因此现在一切都需要使用 try/catch,在这种情况下它确实已被撤销。
只是为了好玩,以下是您可以做完全相同的事情而不必担心抛出的方法(就简单地使用访问器而言;不能保证在您仍然可以访问的情况下做错事):
const RevocableAccess = (item, revoked = false) => ({
access: f => revoked ? undefined : f(item),
revoke: () => { revoked = true; }
});
const { revoke, access: useContext } = RevocableAccess(ctx);
useContext(ctx => ctx.canvas.width = 500);
revoke();
useContext(ctx => ctx.canvas.width = 200); // never fires
正如下面的评论所指出的,我完全忽略了测试宿主对象上的方法调用,事实证明,这些对象都是 protected 。这归结为宿主对象的怪异,它们按照自己的规则进行游戏。
使用上述代理,proxy.drawImage.apply(ctx, args)
就可以正常工作。然而,这是违反直觉的。
我在这里假设失败的情况是 Canvas、Image、Audio、Video、Promise(例如基于实例的方法)等。我还没有讨论这部分 Proxies 的规范,也没有讨论这是属性描述符还是主机绑定(bind),但我假设是后者,如果不是两者都是的话。
也就是说,您应该能够通过以下更改覆盖它:
const { proxy, revoke } = Proxy.revocable(ctx, {
get(object, key) {
if (!(key in object)) {
return undefined;
}
const value = object[key];
return typeof value === "function"
? (...args) => value.apply(object, args)
: value;
}
});
在这里,我仍然“获取”原始对象的方法,以调用它。碰巧的是,在值是函数的情况下,我调用 bind 以返回一个函数,该函数维护与原始上下文的 this
关系。代理通常会处理这种常见的 JS 问题。
...这会引起自身的安全问题;现在,有人可以缓存值,并永久访问 drawImage
,通过说const draw = proxy.drawImage;
...再一次,他们已经有能力保存真实的渲染上下文,只需说const ctx = proxy.canvas.getContext("2d");
...所以我在这里假设有一定程度的善意。
对于更安全的解决方案,还有其他修复方法,尽管使用 Canvas ,除非它仅在内存中,否则上下文最终将可供任何可以读取 DOM 的人使用。
关于javascript - 是否可以将 Proxy 与 native 浏览器对象(HTMLElement、Canvas2DRenderingContext 等)一起使用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48535551/
在这种情况下,我们在应用程序中同时使用react-native-gesture-handler Touchable和react-native Touchable。 (通过Touchables,我的意思
我有一个 MainFooter包含页脚和迷你播放器的组件,单击时动画显示为全 View 。我有一个问题,每当我们点击一个页脚选项卡时,播放器最大化然后卡在那里,没有响应。 此外,播放器内部的向下箭
我在 native react 之上使用 native 基础组件,我想知道如何在 UI 中使卡片呈圆形而不是矩形。有圆形的 Prop 吗? 最佳答案 好吧,实际上没有人能回答这个问题,但幸运的是我在
我在 native react 之上使用 native 基础组件,我想知道如何在 UI 中使卡片呈圆形而不是矩形。有圆形的 Prop 吗? 最佳答案 好吧,实际上没有人能回答这个问题,但幸运的是我在
我是 react-native 的新手,所以我认为“HTML”而不是“native”可能有点太多了,所以我的问题看起来很愚蠢。 我使用 react-native-router-flux 进行路由,并使
当我使用这个例子在我的应用程序上实现 Image-slider 时,我遇到了这个错误。 import React,{Component} from 'react' import {View,T
我正在为我们的产品使用“Native Base”组件,并且效果很好, 但我有一点被卡住了,它是关于将 Items 放入 Nativebase Picker 的问题。我的代码是这样的 渲染方法代码 -
正如文档中所建议的,我将一些长的数据获取代码移动到 native 模块中以释放 JS 线程,但我观察到这仍然阻塞了 UI。为什么会这样,我能做些什么来避免这种情况? 从 JS 调用 native 模块
我正在使用一个名为 react-native-svg 的框架在 React Native View 中绘制 SVG 元素。 我的目标是,当我点击 View 时(我在全局 View 上使用 PanRes
在 IOS 中发现错误 Native Module cannot be null 我不使用 react-native-push-notification 最佳答案 这通常发生在您未能将第三个库链接到您
当应用程序关闭时,我可以获得由 Linking.getInitialURL() 点击的深层链接网址。 .当应用程序处于后台状态时,则不会安装任何内容。所以,我什至无法通过 Linking.addEve
1) 说原生库是什么意思?什么样的图书馆?那些将用作 gradle 依赖项? 2)如何链接这些?我在使用 link 或 rnpm 时遇到了麻烦。 最佳答案 链接 native 库意味着您要将已经实现的
我需要帮助来构建我的 react 原生项目。我尝试过react-native run-android,但出现以下错误: react-native : The term 'react-native' i
我需要帮助来构建我的 react 原生项目。我尝试过react-native run-android,但出现以下错误: react-native : The term 'react-native' i
我是 React-Native 的新手,到目前为止我很喜欢它。我正在尝试创建一个屏幕(用于跨平台应用程序),右上角有一个菜单图标,单击时,我想打开一个菜单,希望使用 react-native-menu
RN doco 和其他示例展示了如何从 native iOS View Controller 启动 React-Native View ,但反之则不然。谁能解释一下我该怎么做? 最佳答案 我能够弄清楚
对于 react-native - WebStorm 用户: 我正在使用 Jet Brains IDE WebStorm 开始一个带有 React Native 的项目。 在项目 => node_mo
在升级过去的 react-native 0.60 之后......我被警告我应该取消链接所有手动链接的第 3 方库(因为 RN 现在通过自动链接处理它)。 但是,当我运行 react-native u
你可以使用像 https://github.com/tolu360/react-native-google-places 这样的库吗?在世博项目中?我假设任何 npm 库都可以添加,但是像这个 goo
我主要喜欢 React Native。自 0.22 以来一直在使用它。目前为 0.35。 但是为什么链接原生库就像抽奖一样呢?我很少在第一次拍摄时让它发挥作用,而破裂的东西通常是完全不同的东西。 每个
我是一名优秀的程序员,十分优秀!