当前位置: 首页 > 面试题库 >

JSON.parse不会在循环对象上出错

哈沛
2023-03-14
问题内容

我正在尝试确定对象是否可以字符串化。此检查在Chrome和Safari中有效,但在FF(25.0.1)中无效。

var good = true;
var myObj = {"param1":11, "param2": "a string", "param3": $("a")}; 
//some cyclic object, specifically I have a jQuery object I got via `$("a")` 
//which returned several anchor tags.

//try to stringify, which supposedly rejects cyclic objects 
try {
    JSON.stringify(myObj);
} catch(error){
    good = false;
}
console.log(good) //returns true.

没有抛出错误…还是我没有正确捕获它?在此之前,我从未打电话给过使用try … catch的经历,所以我对其细微差别的经验是空的。

JSON.stringify(myObj)返回对象的字符串版本,没有许多对象参数,这些参数显然无法进行字符串化。根据MDN,它应该出错。

谢谢!


问题答案:

您正在正确地捕获错误,但是(正如您所确定的)Firefox根本不会引发错误。

这是因为Fiefox不会阻塞DOM对象的JSON化,而其他浏览器却会这样做:

JSON.stringify(document.getElementById("header"))

在Chrome和Safari中,此行会导致错误(因为在WebKit /
Blink中,循环DOM对象(例如同级兄弟)直接存在于每个DOM对象上),而在Firefox中则无害地生成了字符串“ {}”。

这是因为Firefox的DOM对象没有任何自己的可枚举属性:

Object.keys(document.getElementById("header"))
> []

在WebKit /
Blink浏览器中,此行以字符串形式提供属性名称html" target="_blank">数组,因为DOM对象具有自己的属性。JSON.stringify仅捕获对象自身的属性,而不捕获原型属性。

在Firefox中,DOM对象通常不具有自己的属性。相反,属性访问被委派了原型链的HTMLElement.prototypeElement.prototype或者Node.prototype(或元素的直接原型,像HTMLDivElement.prototypeHTMLAnchorElement.prototype)。

您可能想知道: 如果访问DOM元素上的属性导致原型访问,那么DOM元素如何具有不同的属性值? 并非所有DOM元素都具有或多或少相同的原型链吗?

这里的技巧是原型属性没有 ,它们是 getter
函数。例如,当您要求输入firstChildHTMLDivElement,JavaScript引擎执行以下步骤:

  1. firstChild在对象本身上查找属性。不在那里
  2. firstChild在对象的原型上查找属性。
  3. 继续检查原型链,直到我们找到firstChildNode.prototype
  4. Node.prototype.firstChild访问器属性描述符 定义,这意味着属性访问会导致get函数的执行。
  5. this在执行getter函数期间,该值是firstChild您要求其值的特定DOM元素/ Firefox使用该this值对DOM元素的第一个子元素进行了一些幕后查找。

因此,当您这样做时:

var val = document.getElementById("header").firstChild;

您确实在做:

var elm = document.getElementById("header");
var nodeProto = elm.__proto__.__proto__.__proto__.__proto__;
var propDescriptor = Object.getOwnPropertyDescriptor(nodeProto, "firstChild");
var getterFunc = propDescriptor.get;
var val = getterFunc.call(elm);  // invoke the getter with `this` set to `elm`

或(不太可读):

var val = Object.getOwnPropertyDescriptor(document.getElementById("header").__proto__.__proto__.__proto__.__proto__, "firstChild").get.call(document.getElementById("header"))


 类似资料:
  • 我用的是angular 5。我尝试在下面的html数组中使用嵌套循环 对象: HTML: 我得到以下解析错误: 我在app.module.ts导入了BrowserModul和Common Modul,这样用户就可以将一周中的任何一天的时间表复制到一周的其余时间。 编辑:我的代码中的实际超文本标记语言:

  • hasNext()的定义是“如果此扫描仪的输入中有另一个标记,则返回true。此方法可能会在等待输入扫描时阻塞。扫描仪不会前进超过任何输入。” 当我把 standardInput.hasNext() 放在 for 循环中时,程序会向无穷大运行。但是如果我把它放在 while-loop 中,它不会运行到无穷大。这两个程序之间的区别在哪里,为什么其中一个有效而另一个无效? for循环: while-l

  • 这是我使用得到的结果 使用下面的代码,我得到了键列表:值 如何读取特定值,如?我可以使用,但可能还有另一种方法

  • 出现的问题是,当用户确实输入了一个正数时,它仍然忽略输入,并要求用户再次输入一个正整数。我想我只是没有正确退出循环,但我不确定是如何退出的。

  • 问题内容: 刚接触React并尝试循环对象属性,但是React抱怨对象不是有效的React子对象,有人可以给我一些如何解决此问题的建议吗?我添加了createFragment,但不确定是否需要执行此操作或应该采用哪种方法? JS 渲染功能 控制台错误 问题答案: 问题在于您的使用方式,因为它总是会返回。您可能正在寻找返回新数组的方法: 如果仍然要使用,则必须执行以下操作: 更新: 如果您正在编写E

  • 我一直在使用JavaScript代码进行自动GUI测试。我一直在进行全面的测试,并优化了一些代码。例如,我有一个函数可以将值输入到窗口的所有字段中,该窗口大致如下所示: 最初输入函数看起来是这样的:这是相当笨拙的,占用了很多空间,不如编辑函数以接受一个将字段作为属性值的对象那样整洁。现在函数看起来像这样:其中是这样定义的: 在我进入测试一个特殊需求的部分之前,这一直工作得很好,该需求说明当您在窗口