20200115pm

 20200115

 笔试

 输入一堆人名,然后输出格式化的名字比如:list([{name:'Bart'},{name:'Lisa'},{name:'Maggie'}]) return 'Bert,Lisa & Maggie';list([]) return ''


    function list(arr){

        if(Object.prototype.toString.call(arr) !== '\[object Array\]') return 'arr is not an Array';

        let newArr=\[\];

        arr.forEach(element=>{

            if(element.name){

                newArr.push(element.name)

            }else{

                console.log('arr is not contained name');

            }

        });

        let last=newArr.pop();

        let str=newArr.join(',');

        if(last===undefined) return '';

        if(newArr.length===0) return last;

        str+=' & '+last;

        return str;

    }

 输入一个字符串,找出其中最长的不重复的子字符串,并返回子字符串长度。例如:字符长'abcabcbb',最长的不重复的子字符串是'abc',长度是3 写一个函数,参数是一个字符串,返回值是其中最长的不重复的子字符串的长度


    function maxStrLength(str){

        let i=0,res=0,n=0;

        for(let j=0;j

 行内元素有哪些?块级元素有哪些?空(void)元素有哪些?


行内元素:a、b、span、img、input、strong、select、label、em、button、textarea

  
  

块级元素:div、ul、li、dl、dt、dd、p、h1-h6、blockquote

  
  

空元素:即系没有内容的HTML元素,例如:br、meta、hr、link、input、img

 css选择符有哪些?优先级如何计算?


\- 选择器类型:

    - ID  #id

    - class  .class

    - 标签  p

    - 通用  \*

    - 属性  \[type="text"\]

    - 伪类  :hover

    - 伪元素  ::first-line

    - 子选择器、相邻选择器

  

\- 权重计算规则:

    - 第一等:代表内联样式,如: style=””,权值为1000。

    - 第二等:代表ID选择器,如:#content,权值为0100。

    - 第三等:代表类,伪类和属性选择器,如.content,权值为0010。

    - 第四等:代表类型选择器和伪元素选择器,如div p,权值为0001。

    - 通配符、子选择器、相邻选择器等的。如\*、>、+,权值为0000。

    - 继承的样式没有权值。

 使用原生方式或熟悉的JS库写一个AJAX调用,请用JSON数据格式传输和返回


    function getXHR() { //html元素事件触发的函数

        var myXMLHttpRequest = null;

        if (window.ActiveXObject) {

            myXMLHttpRequest = new ActiveXObject("Microsoft.XMLHTTP");

        } else {

            myXMLHttpRequest = new XMLHttpRequest();

        }

        var url = "xxx.php";

        var data = "key=val"; //val一般是从某个html元素中取出的value值

        myXMLHttpRequest.open("post", url, true);

        myXMLHttpRequest.setRequestHeader("Content-Type","application/x-www-form-urlencoded");

        myXMLHttpRequest.onreadystatechange = function(){

            if (myXMLHttpRequest.readyState == 4 && myXMLHttpRequest.status == 200) {

                var res = myXMLHttpRequest.responseText;

                var jsonObj = eval("("+res+")");

                //接下来就可以使用jsonObj这个json对象取出其中的属性值,做一些修改html元素value值等操作了。

            }        

        }

        myXMLHttpRequest.send(data);

    }

jQuery


 response.write("{ username : '"+username+"' , content : '"+content+"'}") 

 由于服务器端返回的数据格式是JSON文档,因此也需要对文档的数据进行处理,但是JSON文档比较XML文档更容易解析。

 $.ajax({

    type:"POST",

    url:"Handler.ashx",

    dataType:json,

    data:{username:$("#name").val(),password:$("#pwd").val()},

    success:function(data){

      var username = data.username;

      var content = data.content;

      var txtHtml = "
"+      username+":
"+content+"

";       $("#result").html(txtHtml)     }  } \`\`\` #### 请用伪代码描述一个排序算法 快速排序 \`\`\` function quickSort(arr,left,right){     let len=arr.length,         partitionIndex,         left=typeof left != 'number' ? 0 : left,         right=typeof right != 'number' ? len-1 : right;     if(left

 JavaScript创建对象的方式有哪几种?

https://www.jianshu.com/p/1fb...


{}

new Object()

使用字面量

工厂模式

构造函数模式(constructor)

原型模式(prototype)

构造函数+原型模式

\`\`\`

  

### 原生js

  

#### 请简述一下js的原型和原型链

\`\`\`

什么是原型链:只要是对象就有原型, 并且原型也是对象, 因此只要定义了一个对象, 那么就可以找到他的原型, 如此反复, 就可以构成一个对象的序列, 这个结构就被称为原型链

所有的实例有一个内部指针(prototype),指向它的原型对象,并且可以访问原型对象上的所有属性和方法。

 js继承有几种方式?

6种


方式一:借助构造函数实现继承

  

这里使用的原理就是在Child里面,把Parent的this指向改为是Child的this指向,从而实现继承

  

function Parent(name){

    this.name=name;

    }

    Parent.prototype.saiHi=function(){

        console.log("hello")

    }

    function Child(name,age,gender){

        Parent.call(this,name)

        this.age=age;

        this.gender=gender;

    }

    let child=new Child("王磊",20,"男")

    console.log(child.name);// 王磊

    child.sayHi(); // Uncaught TypeError:child.sayHi is not a function

缺点:只能解决属性的继承,使用属性的值不重复,但是父级类别的方法不能继承

  

方式二:借助原型链实现继承

  

第二种方式就是把Child的原型改为是Parent的实例,从而实现继承

  

     function Parent(name,gender){

            this.name=name;

            this.gender=gender;

            this.list=\[1,2,3\]

        }

        Parent.prototype.eat=function(){

            console.log("晚餐时间到")

        }

        function Child(age){

            this.age=age;

        }

        Child.prototype=new Parent("李白","男");

        var child=new Child(20);

        var child2=new Child(30);

        child.eat();

        console.log(child.list,child2.list);// \[1,2,3\] \[1,2,3\]

        child.list.push(4)

        console.log(child.list);// \[1,2,3,4\]        

        console.log(child2.list);// \[1,2,3,4\]

缺点:因为Child的原型对象都是New Parent,所以实例化出来的对象的属性都是一样的,而且Parent上面的引用类型只要有一个实例对象修改了,其他也会跟着修改.因为他们原型对象都是共用的

  

方式三:组合型

  

方式三的话是结合了方式一和方式二来实现继承

  

function Person(school){

            this.school=school;

        }

        Person.prototype.skill=function(){

            console.log("学习");

        }

        function Student(school,name,age,gender){

            Parent.call(this,school);

            this.name=name;

            this.age=age;

            this.gender=gender;

        }

        Student.prototype=Person.prototype;

        let student=new Student("广铁一中","王菲菲",14,"女");

        console.log(Student.prototype===Person.prototype)

        console.log(student.constructor)

缺点:父类的原型对象调用了两次,没有必要,而且student实例的构造函数是来自于Person

  

方式四:组合方式优化

  

function Parent(name,play){

            this.name=name;

            this.play=play;

        }

        function Child(name,play,age){

            Parent.call(this,name,play);

            this.age=age;

        }

        Child.prototype=Parent.prototype;

        let child=new Child("张三","玩",20);

        let child2=new Child("李四","吃",10)

        console.log(child,child2)

        console.log(child.prototype===child2.prototype); true

        console.log(child.constructor); // 构造函数指向的是Parent

缺点:child实例的构造函数来自于Parent

  

方式五: 组方式优化

  

只是这种方式的话,你必须得理解Object.create()方法的使用,他创建的对象是在原型上面的

  

function Parent(name,play){

            this.name=name;

            this.play=play;

        }

        function Child(name,play,age){

            Parent.call(this,name,play);

            this.age=age;

        }

        Child.prototype=Object.create(Parent.prototype);// 隔离了父类和子类的构造函数,父类的添加到了\_\_proto\_\_属性上

        Child.prototype.constructor=Child

        let child=new Child("张三","玩",20);

        let child2=new Child("李四","吃",10)

        console.log(child.constructor)

 如何实现promise

完整版


    const PENDING='pending';

    const FULFILLED='fulfilled';

    const REJECTED='rejected';

  

    function MyPromise(fn){

        const self=this;

        self.value=null;

        self.error=null;

        self.status=PENDING;

        self.onFulfilledCallbacks=\[\];

        self.onRejectedCallbacks=\[\];

  

        function resolve(value){

            if(value instanceof MyPromise){

                return value.then(resolve,reject);

            }

            if(self.status===PENDING){

                setTimeout(()=>{

                    self.status=FULFILLED;

                    self.value=value;

                    self.onFulfilledCallbacks.forEach((callback)=>callback(self.value));

                },0)

            }

        }

  

        function reject(error){

            if(self.status===PENDING){

                setTimeout(function(){

                    self.status=REJECTED;

                    self.error=error;

                    self.onRejectedCallbacks.forEach((callback)=>callback(self.error))

                },0)

            }

        }

        try{

            fn(resolve,reject);

        }catch(e){

            reject(e);

        }

    }

  

    function resolvePromise(bridgepromise,x,resolve,reject){

        if(bridgepromise===x){

            return reject(new TypeError('Circular reference'));

        }

  

        let called=false;

        if(x instanceof MyPromise){

            if(x.status===PENDING){

                x.then(y=>{

                    resolvePromise(bridgepromise,y,resolve,reject)

                },error=>{

                    reject(error);

                })

            }else{

                x.then(resolve,reject)

            }

        }else if(x!=null && ((typeof x === 'object') || (typeof x === 'function'))){

            try{

                let then=x.then;

                if(typeof then === 'function'){

                    then.call(x,y=>{

                        if(called) return;

                        called=true;

                        resolvePromise(bridgepromise,y,resolve,reject)

                    },error=>{

                        if(called) return;

                        called=true;

                        reject(error);

                    })

                }else{

                    resolve(x);

                }

            }catch(e){

                if(called) return;

                called=true;

                reject(e);

            }

        }else{

            resolve(x);

        }

    }

  

    MyPromise.prototype.then=function(onFulfilled,onRejected){

        const self=this;

        let bridgePromise;

        onFulfilled=typeof onFulfilled==='function'?onFulfilled:value=>value;

        onRejected=typeof onRejected==='function'?onRejected:error=>{throw error};

        if(self.status===FULFILLED){

            return bridgePromise=new MyPromise((resolve,reject)=>{

                setTimeout(()=>{

                    try{

                        let x=onFulfilled(self.value);

                        resolvePromise(bridgePromise,x,resolve,reject);

                    }catch(e){

                        reject(e);

                    }

                },0)

            })

        }

        if(self.status===REJECTED){

            return bridgePromise=new MyPromise((resolve,reject)=>{

                setTimeout(()=>{

                    try{

                        let x=onRejected(self.error);

                        resolvePromise(bridgePromise,x,resolve,reject);

                    }catch(e){

                        reject(e);

                    }

                },0)

            })

        }

        if(self.status===PENDING){

            return bridgePromise=new MyPromise((resolve,reject)=>{

                self.onFulfilledCallbacks.push((value)=>{

                    try{

                        let x=onFulfilled(value);

                        resolvePromise(bridgePromise,x,resolve,reject)

                    }catch(e){

                        reject(e);

                    }

                });

                self.onRejectedCallbacks.push((error)=>{

                    try{

                        let x=onRejected(error);

                        resolvePromise(bridgePromise,x,resolve,reject);

                    }catch(e){

                        reject(e);

                    }

                });

            });

        }

    }

    MyPromise.prototype.catch=function(onRejected){

        return this.then(null,onRejected);

    }

    MyPromise.deferred=function(){

        let defer={};

        defer.promise=new MyPromise((resolve,reject)=>{

            defer.resolve=resolve;

            defer.reject=reject;

        });

        return defer;

    }

    try{

        module.exports=MyPromise;

    }catch(e){}

简版


    function myPromise(constructor){

        let self=this;

        self.status='pending';

        self.vlaue=undefined;

        self.reason=undefined;

        function resolve(value){

            if(self.status==='pending'){

                self.value=value;

                self.status='resolved';

            }

        }

        function reject(reason){

            if(self.status==='pending'){

                self.reason=reason;

                self.status='rejected';

            }

        }

        try{

            constructor(resolve,reject);

        }catch(e){

            reject(e);

        }

    }

    myPromise.prototype.then=function(onFullfilled,onRejected){

        let self=this;

        switch(self.status){

            case 'resolved':

                onFullfilled(self.value);

                break;

            case 'rejected':

                onRejected(self.reason);

                break;

            default:

        }

    }

 let和var的区别


\- const定义的变量不可以修改,而且必须初始化

\- var定义的变量可以修改,如果不初始化会输出undefined,不会报错。

\- let是块级作用域,函数内部使用let定义后,对函数外部无影响。

 css

 水平垂直居中都有哪些方式?


\- 绝对定位水平垂直居中

     width: 500px;

     height: 300px;

     margin: auto;

     top: 0;

     left: 0;

     bottom: 0;

     right: 0;

     background-color: green;">水平垂直居中
\- 水平垂直居中      width:400px;      height:200px;      top: 50%;      left: 50%;      margin: -100px 0 0 -200px;      background-color: red;">水平垂直居中
\- 水平垂直居中      width:300px;      height:200px;      top: 50%;      left: 50%;      transform: translate(-50%, -50%);      background-color: blue;">水平垂直居中
\- flex 布局居中     flex 布局
  

 如何实现一个烟花爆炸的效果










js烟花效果



document.onclick=function (ev)

{

    var oEvent=ev||event;

    var aDiv=\[\];

    var oDiv=null;

    var \_oDiv=document.createElement('div');

    var i=0;

    var x=oEvent.clientX;

    var y=oEvent.clientY;

    \_oDiv.style.position='absolute';

    \_oDiv.style.background='red';

    \_oDiv.style.width='3px';

    \_oDiv.style.height='30px';

    \_oDiv.style.left=oEvent.clientX+'px';

    \_oDiv.style.top=document.documentElement.clientHeight+'px';

    document.body.appendChild(\_oDiv);

    var t=setInterval(function (){

        if(\_oDiv.offsetTop<=y)

        {

            clearInterval(t);

            show();

            document.body.removeChild(\_oDiv);

        }

        \_oDiv.style.top=\_oDiv.offsetTop-30+'px';

    }, 30);

    function show()

    {

        var oDiv=null;

        for(i=0;i<100;i++)

        {

            oDiv=document.createElement('div');

            oDiv.style.width='3px';

            oDiv.style.height='3px';

            oDiv.style.background='#'+Math.ceil(Math.random()\*0xEFFFFF+0x0FFFFF).toString(16);

            oDiv.style.position='absolute';

            oDiv.style.left=x+'px';

            oDiv.style.top=y+'px';

            var a=Math.random()\*360;

            //oDiv.speedX=Math.random()\*40-20;

            //oDiv.speedY=Math.random()\*40-20;

            oDiv.speedX=Math.sin(a\*180/Math.PI)\*20\*Math.random();

            oDiv.speedY=Math.cos(a\*180/Math.PI)\*20\*Math.random();

            document.body.appendChild(oDiv);

            aDiv.push(oDiv);

        }

    }

    setInterval(doMove, 30);

    function doMove()

    {

        for(i=0;idocument.documentElement.clientWidth || aDiv\[i\].offsetTop<0 || aDiv\[i\].offsetTop>document.documentElement.clientHeight)

            {

                document.body.removeChild(aDiv\[i\]);

                aDiv.splice(i, 1);

            }

        }

    }

};

















    

    css3实现烟花特效

    







    
     \`\`\` ### 框架 #### vue的生命周期都有哪些? \`\`\` Vue 实例从创建到销毁的过程,就是生命周期。从开始创建、初始化数据、编译模板、挂载Dom→渲染、更新→渲染、销毁等一系列过程,称之为 Vue 的生命周期。 生命周期中有多个事件钩子,如下: \- beforeCreate(创建前) 在数据观测和初始化事件还未开始 \- created(创建后) 完成数据观测,属性和方法的运算,初始化事件,$el属性还没有显示出来 \- beforeMount(载入前) 在挂载开始之前被调用,相关的render函数首次被调用。实例已完成以下的配置:编译模板,把data里面的数据和模板生成html。注意此时还没有挂载html到页面上。 \- mounted(载入后) 在el 被新创建的 vm.$el 替换,并挂载到实例上去之后调用。实例已完成以下的配置:用上面编译好的html内容替换el属性指向的DOM对象。完成模板中的html渲染到html页面中。此过程中进行ajax交互。 \- beforeUpdate(更新前) 在数据更新之前调用,发生在虚拟DOM重新渲染和打补丁之前。可以在该钩子中进一步地更改状态,不会触发附加的重渲染过程。 \- updated(更新后) 在由于数据更改导致的虚拟DOM重新渲染和打补丁之后调用。调用时,组件DOM已经更新,所以可以执行依赖于DOM的操作。然而在大多数情况下,应该避免在此期间更改状态,因为这可能会导致更新无限循环。该钩子在服务器端渲染期间不被调用。 \- beforeDestroy(销毁前) 在实例销毁之前调用。实例仍然完全可用。 \- destroyed(销毁后) 在实例销毁之后调用。调用后,所有的事件监听器会被移除,所有的子实例也会被销毁。该钩子在服务器端渲染期间不被调用。

 封装组件需要考虑哪些内容?


开发通用组件是很基础且重要的工作,通用组件必须具备高性能、低耦合的特性

  

一、数据从父组件传入

  

为了解耦,子组件本身就不能生成数据。即使生成了,也只能在组件内部运作,不能传递出去。

  

父对子传参,就需要用到 props,但是通用组件的的应用场景比较复杂,对 props 传递的参数应该添加一些验证规则

  

二、在父组件处理事件

  

在通用组件中,通常会需要有各种事件,

  

比如复选框的 change 事件,或者组件中某个按钮的 click 事件

  

这些事件的处理方法应当尽量放到父组件中,通用组件本身只作为一个中转

  

三、记得留一个 slot

  

一个通用组件,往往不能够完美的适应所有应用场景

  

所以在封装组件的时候,只需要完成组件 80% 的功能,剩下的 20% 让父组件通过 solt 解决

  

四、不要依赖 Vuex

  

父子组件之间是通过 props 和 自定义事件 来传参,非父子组件通常会采用 Vuex 传参

  

但是 Vuex 的设计初衷是用来管理组件状态,虽然可以用来传参,但并不推荐

  

因为 Vuex 类似于一个全局变量,会一直占用内存

  

在写入数据庞大的 state 的时候,就会产生内存泄露

  

五、合理运用 scoped 编写 CSS

  

在编写组件的时候,可以在