在 JavaScript 中,JSON.parse(str);將 JSON 字串轉換為 JavaScript 物件。我發現奇特的是,盡管JSON字串不包含任何資訊__proto__的Object,JSON.parse(str)有時設法恢復的嵌套屬性__proto__屬性。
示例(直接在 Brave 瀏覽器的開發者工具控制臺中運行):
{
let user1 = {
name: "John",
surname: "Smith",
isAdmin: false,
"birthday": new Date(2000, 2, 3),
"friends": [0,1,2,3]
};
user1.__proto__.age = 30;
const str1 = JSON.stringify(user1, null, 2);
user1.__proto__ = null;
user1 = null;
const user2 = JSON.parse(str1);
console.log(str1);
console.log(user2);
const str2 = `{
"name": "John",
"surname": "Smith",
"isAdmin": false,
"birthday": "2000-03-02T15:00:00.000Z",
"friends": [
0,
1,
2,
3
]
}`;
const user3 = JSON.parse(str2);
console.log(user3);
}
在這里, user1 是用這樣的屬性創建的。然后在它的proto 上我分配了 age : 30 屬性。從 user1,我用 制作了它的 JSON 字串JSON.stringify,并將它保存在str1. 現在我洗掉了user1它的__proto__. 只是為了確保,我列印str1出來并沒有關于__proto__和 age:30 的資訊,正如預期的那樣。但是,當我user2從str1with創建時JSON.parse,__proto__的 age:30 恢復了。這怎么可能?現在我什至使用變數名 str2 制作完全相同的 JSON 字串,并使用 str2 創建另一個物件。結果是一樣的。這太瘋狂了。
console.log(str1) 的輸出;
{
"name": "John",
"surname": "Smith",
"isAdmin": false,
"birthday": "2000-03-02T15:00:00.000Z",
"friends": [
0,
1,
2,
3
]
}
console.log(user2) 的輸出;
{name: 'John', surname: 'Smith', isAdmin: false, birthday: '2000-03-02T15:00:00.000Z', friends: Array(4)}
birthday: "2000-03-02T15:00:00.000Z"
friends: (4) [0, 1, 2, 3]
isAdmin: false
name: "John"
surname: "Smith"
[[Prototype]]: Object
age: 30
constructor: ? Object()
hasOwnProperty: ? hasOwnProperty()
isPrototypeOf: ? isPrototypeOf()
propertyIsEnumerable: ? propertyIsEnumerable()
toLocaleString: ? toLocaleString()
toString: ? toString()
valueOf: ? valueOf()
__defineGetter__: ? __defineGetter__()
__defineSetter__: ? __defineSetter__()
__lookupGetter__: ? __lookupGetter__()
__lookupSetter__: ? __lookupSetter__()
__proto__: (...)
get __proto__: ? __proto__()
set __proto__: ? __proto__()
console.log(user3) 的輸出;
{name: 'John', surname: 'Smith', isAdmin: false, birthday: '2000-03-02T15:00:00.000Z', friends: Array(4)}
birthday: "2000-03-02T15:00:00.000Z"
friends: (4) [0, 1, 2, 3]
isAdmin: false
name: "John"
surname: "Smith"
[[Prototype]]: Object
age: 30
constructor: ? Object()
hasOwnProperty: ? hasOwnProperty()
isPrototypeOf: ? isPrototypeOf()
propertyIsEnumerable: ? propertyIsEnumerable()
toLocaleString: ? toLocaleString()
toString: ? toString()
valueOf: ? valueOf()
__defineGetter__: ? __defineGetter__()
__defineSetter__: ? __defineSetter__()
__lookupGetter__: ? __lookupGetter__()
__lookupSetter__: ? __lookupSetter__()
__proto__: (...)
get __proto__: ? __proto__()
set __proto__: ? __proto__()
By the way I turned the browser off and on and reran the code block to make sure it wasn't a result of some pre assigned variables. The result was the same and it (age: 30) wasn't coming from pre assigned variables or cached value whatsoever.
Also I opened a fresh tab and executed the following smaller code block.
{
const str2 = `{
"name": "John",
"surname": "Smith",
"isAdmin": false,
"birthday": "2000-03-02T15:00:00.000Z",
"friends": [
0,
1,
2,
3
]
}`;
const user3 = JSON.parse(str2);
console.log(user3);
}
In this case, age: 30 property in the proto is not there, which is the original expected result to have happened with first example, at least for me.
Output with smaller code block:
{name: 'John', surname: 'Smith', isAdmin: false, birthday: '2000-03-02T15:00:00.000Z', friends: Array(4)}
birthday: "2000-03-02T15:00:00.000Z"
friends: (4) [0, 1, 2, 3]
isAdmin: false
name: "John"
surname: "Smith"
[[Prototype]]: Object
constructor: ? Object()
hasOwnProperty: ? hasOwnProperty()
isPrototypeOf: ? isPrototypeOf()
propertyIsEnumerable: ? propertyIsEnumerable()
toLocaleString: ? toLocaleString()
toString: ? toString()
valueOf: ? valueOf()
__defineGetter__: ? __defineGetter__()
__defineSetter__: ? __defineSetter__()
__lookupGetter__: ? __lookupGetter__()
__lookupSetter__: ? __lookupSetter__()
__proto__: (...)
get __proto__: ? __proto__()
set __proto__: ? __proto__()
uj5u.com熱心網友回復:
所以看起來我誤用了原型。洗掉年齡的正確方法:30 是
任何一個
delete user1.__proto__.age;
或者
delete Object.prototype.age;
而這里user1=null無關緊要。
由于某種原因user1.__proto__ = null一事無成,如果有人暗示我為什么會很好
編輯:user1.__proto__ = null確實洗掉了 user1 的原型,但它不影響 Object.prototype。我認為它只會將 user1 從原型鏈中分離出來。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/395889.html
標籤:javascript json parsing prototype
上一篇:沒有標簽的antlr4節點
