refactor: make the set method more reasonable#7981
Conversation
src/core/observer/index.js
Outdated
| /* eslint-disable no-self-compare */ | ||
| if (newVal === value || (newVal !== newVal && value !== value)) { | ||
| if ( | ||
| (getter && !setter) || |
There was a problem hiding this comment.
Then when have the chance to invoke customSetter?
There was a problem hiding this comment.
The following content is my understanding, there may be incorrect place.
The first thing we can guarantee is that if the value of the property property is undefined, both the value of getter and setter will be undefined:
/* defineReactive */
const property = Object.getOwnPropertyDescriptor(obj, key)
// If `property === undefined`, both `setter` and `getter` are undefined
const getter = property && property.get
const setter = property && property.setThe customSetter method is mainly used to print prompt information when the property value is set, and mainly used in the following aspects:
- Define the injected value on the instance object:
/* inject.js initInjections */
defineReactive(vm, key, result[key], customSetter)At this point, the return value of Object.getOwnPropertyDescriptor(vm, key) is undefined, so both getter and setter are undefined
- Define the
$attrsand$listenersproperties on the instance object:
/* render.js initRender */
defineReactive(vm, '$attrs', parentData && parentData.attrs || emptyObject, () => {
!isUpdatingChildComponent && warn(`$attrs is readonly.`, vm)
}, true)
defineReactive(vm, '$listeners', options._parentListeners || emptyObject, () => {
!isUpdatingChildComponent && warn(`$listeners is readonly.`, vm)
}, true)We can still guarantee that the following statement's value is undefined:
Object.getOwnPropertyDescriptor(vm, '$attrs') // undefined
Object.getOwnPropertyDescriptor(vm, '$listeners') // undefined- Define the props data on the
vm._propsobject:
/* state initProps */
const props = vm._props = {}
defineReactive(props, key, value, customSetter)The value of Object.getOwnPropertyDescriptor(props, key) is undefined。
In summary, when the value of the Object.getOwnPropertyDescriptor method is undefined, both the getter and the setter are undefined, so (getter && !setter) will always be false and will not affect the execution of the customSetter.
There was a problem hiding this comment.
But won't it make the code harder to maintain? Since every time you add a call to defineReactive with customSetter you'll have to check all these conditions.
IMHO, as this refactor aims to get rid of unnecessary observation, putting the getter and setter check right before assigning to val might be easier to understand.
|
niubi |
This comment has been minimized.
This comment has been minimized.
|
厉害厉害 |
What kind of change does this PR introduce? (check at least one)
Does this PR introduce a breaking change? (check one)
If yes, please describe the impact and migration path for existing applications:
The PR fulfills these requirements:
devbranch for v2.x (or to a previous version branch), not themasterbranchfix #xxx[,#xxx], where "xxx" is the issue number)If adding a new feature, the PR's description includes:
Other information:
Please check: #7280 (comment)