js函数生命周期

发布网友

我来回答

6个回答

懂视网

本篇文章给大家带来的内容是关于JavaScript实现自定义生命周期的方法(代码示例),有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助。

React,Vue 和 Angular 的流行,让“生命周期”这个名词常常出现在前端们的口中,以至于面试中最常见的一个问题也是:

介绍下React, Vue的生命周期以及使用方法?

听起来高大上的“生命周期”,其实也就是一些普通的方法,只是在不同的时期传参调用它们而已。我们可以照着React的生命周期,自己模拟一个简单的类,并让这个类拥有一些生命周期钩子

我们希望实现一个State类,这个类拥有以下方法和生命周期:

方法:

  • setState

  • 生命周期:

  • willStateUpdate (nextState): 状态将要改变

  • shouldStateUpdate (nextState): 是否要让状态改变,只有返回true才会改变状态

  • didStateUpdate (prevState): 状态改变后(要是 shouldStateUpdate 返回的不为true则不会调用)

  • <!-- more -->

    class User extends State {
     constructor(name) {
     super();
     this.state = { name }
     }
    
     willStateUpdate(nextState) {
     console.log('willStateUpdate', nextState);
     }
    
     shouldStateUpdate(nextState) {
     console.log('shouldStateUpdate', nextState);
     if (nextState.name === this.state.name) {
     return false;
     }
    
     return true;
     }
    
     didStateUpdate(prevState) {
     console.log('didStateUpdate', prevState);
     }
    }
    
    const user = new User('deepred');
    
    user.setState({ name: 'hentai' });

    首先,你需要知道JavaScript的面向对象基础知识,如果还不是很了解,可以先看下这篇文章JavaScript的面向对象

    setState的实现

    class State {
     constructor() {
     this.state = {};
     }
    
     setState(nextState) {
     const preState = this.state;
     this.state = {
     ...preState,
     ...nextState,
     };
     }
    }
    class User extends State {
     constructor(name) {
     super();
     this.state = {
     name
     }
     }
    }
    const user = new User('tc');
    
    user.setState({age: 10}); // {name: 'tc', age: 10}

    在React中,setState方法只会改变特定属性的值,因此,我们需要在方法里用一个变量preState保留之前的state,然后通过展开运算符,将新旧state合并

    willStateUpdate的实现

    willStateUpdate是state状态更新前调用的。因此只要在合并state前调用willStateUpdate就行

    class State {
     constructor() {
     this.state = {};
     }
    
     setState(nextState) {
     // 更新前调用willStateUpdate
     this.willStateUpdate(nextState);
     const preState = this.state;
     this.state = {
     ...preState,
     ...nextState,
     };
     }
    
     willStateUpdate() {
     // 默认啥也不做
     }
    
    }
    class User extends State {
     constructor(name) {
     super();
     this.state = {
     name
     }
     }
    
     // 覆盖父级同名方法
     willStateUpdate(nextState) {
     console.log('willStateUpdate', nextState);
     }
    }
    
    const user = new User('tc');
    
    user.setState({age: 10}); // {name: 'tc', age: 10}

    shouldStateUpdate的实现

    我们规定只有shouldStateUpdate返回true时,才更新state。因此在合并state前,还要调用shouldStateUpdate

    class State {
     constructor() {
     this.state = {};
     }
    
     setState(nextState) {
     this.willStateUpdate(nextState);
     const update = this.shouldStateUpdate(nextState);
     if (update) {
     const preState = this.state;
     this.state = {
     ...preState,
     ...nextState,
     };
     }
     }
    
     willStateUpdate() {
     // 默认啥也不做
     }
    
     shouldStateUpdate() {
     // 默认返回true,一直都是更新
     return true;
     }
    
    }
    class User extends State {
     constructor(name) {
     super();
     this.state = {
     name
     }
     }
    
     // 覆盖父级同名方法
     willStateUpdate(nextState) {
     console.log('willStateUpdate', nextState);
     }
    
     // 自定义何时更新
     shouldStateUpdate(nextState) {
     if (nextState.name === this.state.name) {
     return false;
     }
    
     return true;
     }
    }
    
    
    const user = new User('tc');
    
    user.setState({ age: 10 }); // {name: 'tc', age: 10}
    
    user.setState({ name: 'tc', age: 11 }); // 没有更新

    didStateUpdate的实现

    懂了willStateUpdate也就知道didStateUpdate如何实现了

    class State {
     constructor() {
     this.state = {};
     }
     setState(nextState) {
     this.willStateUpdate(nextState);
     const update = this.shouldStateUpdate(nextState);
     if (update) {
     const preState = this.state;
     this.state = {
     ...preState,
     ...nextState,
     };
     this.didStateUpdate(preState);
     }
     }
     willStateUpdate() {
     // 默认啥也不做
     }
     didStateUpdate() {
     // 默认啥也不做
     }
     shouldStateUpdate() {
     // 默认返回true,一直都是更新
     return true;
     }
    
    }
    class User extends State {
     constructor(name) {
     super();
     this.state = {
     name
     }
     }
     // 覆盖父级同名方法
     willStateUpdate(nextState) {
     console.log('willStateUpdate', nextState);
     }
     // 覆盖父级同名方法
     didStateUpdate(preState) {
     console.log('didStateUpdate', preState);
     }
    
     shouldStateUpdate(nextState) {
     console.log('shouldStateUpdate', nextState);
     if (nextState.name === this.state.name) {
     return false;
     }
    
     return true;
     }
    }
    const user = new User('tc');
    user.setState({ age: 10 }); 
    user.setState({ name: 'tc', age: 11 });

    通过几十行的代码,我们就已经实现了一个自带生命周期的State类了!

    热心网友

    老师讲课内容:

    函数生命周期:

       1. 开始执行前:

    创建执行环境栈(数组): 临时保存正在执行的函数的执行环境

              向执行环境栈中压入第一个默认函数main()

              创建全局作用域对象window

       2. 定义函数时:

    创建函数对象,封装函数定义

         声明函数名变量,引用函数对象

         函数对象的scope属性引用回创建函数时的作用域

       3. 调用函数时:

    ECS中压入一个新的元素(执行环境)记录新函数的调用

         创建一个活动对象,保存本次函数调用用到的局部变量

         ECS中的新执行环境元素,引用活动对象

         活动对象中的parent属性引用函数的scope指向的父级作用域对象

         执行过程中: 优先使用活动对象中的局部变量

                    局部没有,才延parent向父级作用域找

       4. 函数调用后:

         执行环境栈中本次函数的执行环境出栈

           导致活动对象被释放

             导致局部变量一同释放

    图示:

    前三步

    第四步

    热心网友

    个人理解函数生命周期就是函数的作用范围即作用域的问题,js里的函数可能只在这一个js里有用、还可能在其他地方也可以用。不过我对javascript不太熟,不知道有没有帮到你!

    热心网友

    js程度的生命周期是从浏览器发出请求到再次刷新或跳转页面这个时间段,生命周期结束后,js定义的变量和对象绝大部分会被注销,资源得到释放

    热心网友

    javascript 啊,页面打开就有了,页面关掉就没了追问那函数周期在js中有什么作用吗 没有不同的情况或特例吗

    追答应该没有吧,我做了几年js,也没搞过这些没啥用的概念

    热心网友

    JS中,函数分成很多种,因为JS本身是弱数据类型语言导致很多语法不够明确有二义性。
    <script>
    function a(){}
    </script>
    这样子的函数就属于全局的函数,那么就是属于楼上兄弟说的开页面就有,关页面就没的状态。
    <script>
    function a(){
    function b(){};
    }
    </script>
    而这种写法呢,b方法是只有当a被实例化时才有的一个方法,而且外部是不能访问的,类似一个私有方法。
    建议参考《javascript权威指南》一书中的对应章节,讲的很明确,自己再做几个小实验就清楚了

    声明声明:本网页内容为用户发布,旨在传播知识,不代表本网认同其观点,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。E-MAIL:11247931@qq.com