Skip to content
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

有赞: 为什么在类实例中可以访问this.setState (二面) #11

Open
baohuse opened this issue Apr 30, 2019 · 1 comment
Open

Comments

@baohuse
Copy link

baohuse commented Apr 30, 2019

To:
baohuse

面试公司:
有赞

面试环节:
二面

问题:
为什么在类实例中可以访问this.setState

@baohuse
Copy link
Author

baohuse commented Apr 30, 2019

在我们编写 class component的过程中,我们会在组件内部使用this.setState来改变 state,触发 re-render,但是疑惑🤔的是,我们并没有在 class里面写 setState这个方法,嗯,他是在父类 Component 里面定义的,那么疑惑🤔又来了,子类的实例对象是怎么查找到找个方法的,为了回答这个问题,我们得先理解下原型链这个概念

原型链
javascript每一个对象身上都有一个原型(proto),当我们写 fred.sayHi() 但 fred自身并没有sayHi属性时, fred 对象会尝试去原型上找sayHi属性,要是在这人还找不到,就去找原型链的下一个原型, fred 的原型的原型,以此类推

因此 [原型链 ] 更像是 proto.proto.proto...

那么他跟 Fun的prototype有什么关系呢? 在过去,js并没有类的概念,但是你可以使用普通函数来模拟,具体来讲,在函数调用时在它前面加一个new 的操作符,那么这个函数就可以称作类的构造函数了,例如
image

我们使用new Person这个构造函数来产生了一个对象, 那么这个new 有何神奇之处呢? 可以看到他把 Person.prototype上的东西放到 fred对象的 __protp__属性上了,

如果调用你Person('Fred')时没有加new,的其中this会指向某个全局无用的东西(比如,window或者undefined),因此我们的代码会崩溃,做或者一些像设置window.name之类的傻事。

通过在调用前增加new,我们说:“嘿JavaScript,我知道Person只是个函数,但让我们假装它是个构造函数吧。创建一个{}对象并把Person中this指向那个对象,以便我可以通过类似this.name的形式去设置一些东西,然后把这个对象返回给我。」

就是这new操作符所做的事

👌,清楚了__proto_跟prototype之间的关系后,(就是new调用那个类或者函数生成对象的__proto__指向那个函数的prototype)我们再来聊下fred对象是怎么找到sayHi的

image

当我们说 obj.name 时, javascript事实上会沿着 obj, obj.proto,obj.proto.__proto__等一路寻找 name属性

so,那个__protp__才是javascript用来查找属性的,那回到主题,继承与React.Component类的组件是怎样找到this.setState的, 在这之前,我们得先明白一件事, fred是与 "Person" 类中的this等效(一般说this指向实例对象)
image

在使用类class时,extends并非直接面对这一机制,但的原理依然是基于这项老旧但有效的原型链机制。这也是的我们的React类实例能够访问如此样setState方法的原因

当Greeting extends React.Componet时他的继承关系如下

image

结语

现在我们理解了为什么可以在extend与 Component的类中使用this.setState 了, 随着业务的复杂,除了将页面拆成大大小小的基础组件跟业务组件外,我们可以充分利用继承来实现场景话的应用,比如阿里云的mix, 这样可以减少很多的工作量,只关注配置跟业务,可能会更加

f(state) => ui 吧

Reference

@acodercc acodercc added this to the 已回答 milestone Apr 30, 2019
@acodercc acodercc changed the title To baohuse: 为什么在类实例中可以访问this.setState (有赞) 有赞: 为什么在类实例中可以访问this.setState (二面) May 6, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants