-
Notifications
You must be signed in to change notification settings - Fork 1.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
面试官:为什么data属性是一个函数而不是一个对象? #9
Comments
面试官:为什么data属性是一个函数而不是一个对象?一、实例和组件定义data的区别
const app = new Vue({
el:"#app",
// 对象格式
data:{
foo:"foo"
},
// 函数格式
data(){
return {
foo:"foo"
}
}
}) 组件中定义 如果为组件 Vue.component('component1',{
template:`<div>组件</div>`,
data:{
foo:"foo"
}
}) 则会得到警告信息 警告说明:返回的 二、组件data定义函数与对象的区别上面讲到组件 在我们定义好一个组件的时候, 这里我们模仿组件构造函数,定义 function Component(){
}
Component.prototype.data = {
count : 0
} 创建两个组件实例
修改 console.log(componentB.data.count) // 0
componentA.data.count = 1
console.log(componentB.data.count) // 1 产生这样的原因这是两者共用了同一个内存地址, 如果我们采用函数的形式,则不会出现这种情况(函数返回的对象内存地址并不相同) function Component(){
this.data = this.data()
}
Component.prototype.data = function (){
return {
count : 0
}
} 修改 console.log(componentB.data.count) // 0
componentA.data.count = 1
console.log(componentB.data.count) // 0
三、原理分析首先可以看看 源码位置: function initData (vm: Component) {
let data = vm.$options.data
data = vm._data = typeof data === 'function'
? getData(data, vm)
: data || {}
...
}
别急,继续看下文 组件在创建的时候,会进行选项的合并 源码位置: 自定义组件会进入 Vue.prototype._init = function (options?: Object) {
...
// merge options
if (options && options._isComponent) {
// optimize internal component instantiation
// since dynamic options merging is pretty slow, and none of the
// internal component options needs special treatment.
initInternalComponent(vm, options)
} else {
vm.$options = mergeOptions(
resolveConstructorOptions(vm.constructor),
options || {},
vm
)
}
...
} 定义 源码位置: 这时候 strats.data = function (
parentVal: any,
childVal: any,
vm?: Component
): ?Function {
if (!vm) {
if (childVal && typeof childVal !== "function") {
process.env.NODE_ENV !== "production" &&
warn(
'The "data" option should be a function ' +
"that returns a per-instance value in component " +
"definitions.",
vm
);
return parentVal;
}
return mergeDataOrFn(parentVal, childVal);
}
return mergeDataOrFn(parentVal, childVal, vm);
}; 四、结论
|
问个问题,为什么React的state不需要返回一个函数? |
类组件,你看看你写state的时候加static了吗?state又不是静态属性,不在原型上,在实例对象上,都是独立的 |
回答的真好 确实是在每一个组件上 |
为什么不只支持函数呢?支持对象的意义何在?有什么场景是只能传对象,不能传函数的吗? |
意思就是定义成函数,函数会有各自的域不会影响其他的 ,而定义对象他们会指向一个地址会互相污染干扰 |
因为设置成函数的 然后return出去会形成闭包。 |
感觉文章还有一点误导,其实文章想表达的是“怕同一个data对象,应用到了两个不同的组件中,任意一个组件被修改,另一个组件也会受影响”吧 |
为什么data要挂在prototype上呢?不能每个类实例维护自己的data吗? |
本来就是实例维护自己的data啊... |
function Component(){
}
Component.prototype.data = {
count : 0
} 我是对上述这段代码提出疑问,为什么不是 function Component(){
this.data = {
count: 0
}
} 出于什么考量吗 |
确实,vue在构建实例的时候将data的归属放在实例里,而不是构造函数内部,是不是就不存在这个问题了 |
看源码就知道啦 做成函数是为了形成闭包啦 这样就可以避免产生数据污染 |
No description provided.
The text was updated successfully, but these errors were encountered: