Cauz only Object
, Array
, Map
, Set
, WeakMap
and WeakSet
can be acted for in Vue 3 reactivity system. And to value of the type of Object
called by Object.isFrozen
returns true
or with __v_skip
unenumerable property of which value is true
will can not proxied as well. VNode is one of the folks has a true __v_skip
unenumerable property.
And what markRaw
does is to make an object to be out of work in reactivity system. And the implementation is straight forward, as VNode does.
export function markRaw<T extends object>(value: T): T {
Object.defineProperty(value, '__v_skip', {
configurable: true,
enumerable: false,
value
})
return value
}
The source code reading is over there, too simple to do analysis, yeah. But what I wanna do is to dig a bit deeper in object.isFrozen
. Let’s kick start.
Object.isExtensible
By default, Object
s (including Array
) are extensible. That means they can have new properties added to them. And Object.isExtensible
is used to determine whether an object is extensible.
Important Note: calling Object.isExtensible
with the target object returns true
, that just means it cannot have additional properties but it doesn’t matter to neither removing nor updating exist properties.
In ES5, if an argument to Object.isExtensible
is not an object(primitive value), then it will raise a TypeError
because of there is no non-object coercion. But in ES2015, that turned out to treat the non-object argument as if it was a non-extensible ordinary object, and return false
constantly.
And an object can be marked as non-extensible by the following methods
Object.preventExtensions
Object.seal
object.freeze
Let’s have some examples
let names = [
'John',
'Mary'
]
Object.preventExtensions(names)
names.push('Tim') // raise `TypeError`
names.remove('John') // it works, ['Mary']
names[0] = 'John' // it turns out to ['John']
How about the corresponding Reflect.isExtensible
Reflect.isExtensible
takes the same argument and returns the same result as Object.isExtensible
does, but it would not coerce non-object value into non-extensible ordinary one, throws an TypeError
instead.
More constraints with Object.isSeal
Object.isSeal
method determines if an object is sealed. But what is sealed for an object? In addition to what the non-extensible object does, all properties of sealed object are not removable(a.k.a. non-configurable). However, all its properties are writable still.
Show me instance
let John = {
nationality: 'China',
province: 'GuangDong',
city: 'FoShan',
hobby: 'skateboard'
}
John.likeSmoking = true // raise `TypeError`, cauz I really don't like having cigarette ;)
delete John.hobby // raise `TypeError`, it's boring with no hobby in your spare time.
John.hobby = 'popping dance' // oh, it works :)
At the last, there is no Reflect.isSeal
, and Object.isSeal
has the catches as Object.isExtensible
, but returns true
with non-object input always in ES2015 instead.
The most strict folk Object.isFrozen
A frozen object is that guy with non-extensible, all its properties are not removable or writable. Non-writable properties can be defined in two ways. One is defining accessor property with getter component only. The other is defining by Object.defineProperty
with writable: true
option.
let John = {
nationality: 'China',
province: 'GuangDong',
city: 'FoShan',
hobby: 'skateboard'
}
John.likeSmoking = true // raise `TypeError`, cauz I really don't like having cigarette ;)
delete John.hobby // raise `TypeError`, it's boring with no hobby in your spare time.
John.hobby = 'popping dance' // raise `TypeError`, oh no! I can not change what I like :(
Finally, there is no Reflect.isSeal
neither. But Object.isFrozen
has the catches as Object.isExtensible
, but returns true
with non-object input always in ES2015 instead.