简体   繁体   English

这个代理总是在代理上抛出 'set' 是否有原因:trap 为属性 'main' 返回 falsish 但在其他情况下仍然可以完美运行?

[英]Is there a reason why this Proxy always throws 'set' on proxy: trap returned falsish for property 'main' but still runs perfectly otherwise?

I am working on a project with javascript where I am trying to make something sort of like AngularJS , but a little different and just for fun, because I think that data-binding is a really cool idea and it is very useful when implemented correctly.我正在使用 javascript 开发一个项目,我正在尝试制作类似AngularJS东西,但有点不同,只是为了好玩,因为我认为数据绑定是一个非常酷的想法,并且在正确实施时非常有用。 I have a Proxy Object defined to detect when changes occur, and some functions to handle the HTML and data-binding.我定义了一个Proxy对象来检测何时发生更改,以及一些处理 HTML 和数据绑定的函数。 It is working, and will replace something like this where (main = 'hello'):它正在工作,并将替换如下内容(main = 'hello'):

<div>
  %{ main }%
</div>

with this:有了这个:

<div class = 'binding-0'>
  hello
</div>

and if 'main' changes to something else, the div element will also change its value.如果 'main' 更改为其他内容, div元素也将更改其值。 However, for whenever I use the set method I have defined for the global object to handle all the variables found in the html, I get this error:但是,每当我使用我为全局对象定义的set方法来处理在 html 中找到的所有变量时,我都会收到此错误:

Uncaught TypeError: 'set' on proxy: trap returned falsish for property 'main'
    at app.js:112

Any idea why?知道为什么吗? It still does what it is supposed to, but always throws this error.它仍然会做它应该做的事情,但总是抛出这个错误。
Here is the code:这是代码:

 'use strict' let global; global = new Proxy({}, { set: function(target, property, value) { target[property] = value; doEval(); }, configurable: true, writable: true }); let set = {}; let elements = []; const find = document, a = (qs) => find.querySelector(qs), b = (cn) => find.getElementsByClassName(cn), c = (tn) => find.getElementsByTagName(tn); Element.prototype.evaluate = function() { let element = this; if (element.children.length < 1) { let split = element.innerText.split(/\\%{|\\}%/gi); let bindingNum = element.className.split('binding')[1]; if (split[1] !== undefined) { if (elements[bindingNum]) { element.outerHTML = elements.indexOf(bindingNum); } else { elements.push(element.outerHTML); element.className = 'binding-' + elements.indexOf(element.outerHTML); elements.pop(); elements.push(element.outerHTML); } endEval(element); } else { if (bindingNum == -0) { bindingNum = 0; } if (elements[bindingNum]) { element.outerHTML = elements[bindingNum]; element = a('.' + element.className); endEval(element); } } } }; Object.defineProperty(Element.prototype, 'actions', { set: function(action) { let element = this; if (action.js) { Object.entries(action.js).forEach(function(event) { element.addEventListener(event[0], event[1], false); }); } if (action.css) { Object.entries(action.css).forEach(function(style) { element.style[style[0]] = style[1]; }) } }, get: function() { return { css: this.style } } }); function doEval() { Array.from(c('*')).forEach(function(element) { element.evaluate(); }); } function endEval(element) { let newSplit = element.innerText.split(/\\%|\\%/gi); element.innerText = null; newSplit.forEach(function(prop) { if (prop.includes('{') && prop.includes('}')) { let finalProp = prop.split(/\\{|\\}/gi)[1].trim(); if (global[finalProp] !== undefined) { element.innerHTML += global[finalProp]; } else { global[finalProp]; console.warn(finalProp + ' is not defined'); } } else { element.innerHTML += prop; } }); } window.onload = doEval; a('.click-me').actions = { js: { click: function() { global.main++; } }, css: { userSelect: 'none' } } global.main = 0;
 <!doctype html> <html> <head></head> <body> <div> %{ main }% </div> <div class='click-me'> Click me! </div> <script src='app.js'></script> </body> </html>

I do not now how to get this to work without throwing the error.我现在不知道如何在不抛出错误的情况下使其正常工作。 I have a tried a try {} catch (TypeError) {} in different places with no luck.我在不同的地方尝试过try {} catch (TypeError) {} ,但没有成功。

According to the MDN Proxy docs :根据MDN 代理文档

The set method should return a boolean value. set方法应该返回一个布尔值。 Return true to indicate that assignment succeeded.返回true表示赋值成功。 If the set method returns false , and the assignment happened in strict-mode code, a TypeError will be thrown.如果 set 方法返回false ,并且赋值发生在严格模式代码中,则会抛出TypeError

Your set method does not return a boolean value (specifically true ), so according to these docs you should be getting a TypeError in strict mode.您的set方法不返回布尔值(特别是true ),因此根据这些文档,您应该在严格模式下收到 TypeError 。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM