es6,ts以及vue测试

1.简述vue生命周期?

   1)beforeCreate:数据劫持 data -> vue

      created:vue实例创建完毕,可以通过this来直接访问data,methods中的属性

   2)beforeMount:此时具有渲染函数,template 模板-->产生 渲染函数 render

      mounted:已经完成了初步绑定,render完成渲染(生命周期构造函数)执行ajax

   3)------------数据改变-----------------

      beforeUpdate:在重新渲染之前执行

      updated:完成了重新渲染

   4)beforeDestroy:在销毁之前,释放资源

      destroyed:销毁后

        

2.什么是插槽?你用过哪些插槽?

插槽,它是vue提出的一个概念,插槽用于决定将所携带的内容,插入到指定的某个位置,使得模块分块,具有模块化特质。插槽的指令为v-slot,它目前取代了slot和slot-scope,插槽内容,vue实例一套内容分发的api,将slot元素作为承载分发内容的出口。

插槽有三种,默认,具名,作用域。

3.vue中key的作用

v-bind:key="唯一值"

     在列表渲染的时候,在重复的元素上务必添加一个key,表示唯一值

        利于Diff算法对dom操作进行优化(效率偏低,但是准确度高)

4.使用Promise封装ajax?

function(url,{ params={}, headers={} }){

return new Promise((resolve,reject)=>{

  //1.初始化xhr

      let xhr = new XMLHttpRequest();

//2.设置请求行

      url = url+'?'+Qs.stringify(params)

      xhr.open('GET',url)

//3.设置请求头

      for(let k in headers){

        let v = headers[k]

        xhr.setRequestHeader(k,v)

      }

//4.设置请求体

      xhr.send()

     //5.监听响应

      xhr.onreadystatechange = function(){

        if(this.readyState === 4){

          if(this.status === 200){

            let resp = JSON.parse(this.response)

            resolve(resp) // 标识承诺成功

          } else {

            let error = JSON.parse(this.response)

            reject(error) // 标识承诺失败

          }

        }

      }

    }

5.什么是跨域?如何解决跨域问题?

A网站想要获取B网站服务器上的资源,网站通过AJAX发送请求的时候,本地服务器地址与请求地址、协议类型(http)、IP地址(域名)、端口,三者有其一不同都称之为跨域请求资源

解决跨域问题:

1.CORS:cors是一个W3C制定的跨域标准,全称是:Cross-origin resource sharing,这句话的含义就是跨域资源共享,这种方式主要应用在服务端。

他是通过设置服务端设置一个HTTP头:setHeader("Access-Control-Allow-Origin", "*")

如果Access-Control-Allow-Origin中有A,或者是通配符*,浏览器就会允许A跨域,通配符代表任何地址都能跨域。

客户端不需要作任何设置,还是按照AJAX请求一样,这样就能获取跨域资源。

  1. JSONP:jsonp是通过script标签的src属性,我们都知道src属性能获取同一个ip服务器上,不同文件夹的文件,它其实就是一个HTTP请求,而且它支持跨域,不需要服务端设置直接就能跨域获取资源。

6.CommonJS模块与ES模块的区别?

1)CommonJS 模块化

      社区提供的    

        半深拷贝

        console.log("index模块中:", a.num);//1

        console.log("index模块中:", a.obj.num);//2

        1.模块的暴露

            模块内部的变量其他模块无法访问,如果想要其他模块进行访问,

需要进行接口的暴露

            module.exports

            module是一个对象,每个模块都拥有这个对象,

            exports属性是用于将当前目录信息传递到其他模块,

其默认值是一个空对象

            1.module.exports.xxx

            2.module.exports={}

        2.模块导入

            require(模块)

            1.当模块为自定义模块时,参数为文件路径

              require('./a.js')

            2.当模块为内置模块时,参数为模块名称

              require('http')

            3.当模块为第三方模块时,参数为模块名称,但是需要先进行模块的安装

              >cnpm install axios --save

              require('axios')

            模块引入的本质就是获取被引入模块中的module.exports属性

2)ES6 模块化

      官方提供的

      如果想要让nodejs支持es6模块化,nodejs版本v14+,

      package.json添加一个配置项type:"module"

        1.模块的暴露

            1.export 声明

              多次使用,使用哪个遍历暴露,就要使用哪个变量获取

            2.export default

              仅可使用一次,可以使用任意变量名来获取

            一个模块中可以既使用export又使用export default

        2.模块导入

            import aa from './a.js'

7.简述for-in、for-of、forEach区别?

for-in:遍历数组索引、对象的属性

for-of:遍历数组,字符串的值

forEach:遍历数组

8.谈谈你对this的理解?

谁调用指向谁

  1. 箭头函数:this指向包含它的外层函数的this
  2. 单独使用thi指代全局

浏览器中指window对象

node环境中指global对象

3)函数内使用this

函数的所属者默认绑定到this上

4)事件中的this

this指向接收事件的HTML元素

9.ES6 中的 Set如何使用,如何实现自己的 Set

Set:不可以存放相同的值,不可以通过索引来访问(没有索引)。

Set是一种特殊的Map

使用:数组去重

    let arr=[1,2,3,1,2,3];

    let result=[...new Set(arr)];

//实现自己的Set

class Set {

    constructor(iterable) {

        this.value = [];

        if (!this instanceof Set) throw new Error('Constructor Set requires "new"');

        if (isDef(iterable)) {

            if (typeof iterable[Symbol.iterator] !== 'function') new Error(`${iterable} is not iterable`);

            // 循环可迭代对象,初始化

            forOf(iterable, value => this.add(value));

        }

    }



    get size() {

        return this.value.length;

    }



    has(val) {

        return this.value.includes(val); // [ NaN ].includes(NaN)会返回true,正好Set也只能存一个NaN

    }

    add(val) {

        if (!this.has(val)) {

            this.value.push(val);

        }

        return this;

    }

    delete(val) {

        const index = this.value.indexOf(val);

        if (index > -1) {

            this.value.splice(index, 1);

            return true;

        }

        return false;

    }

    clear() {

        this.value.length = 0;

    }

    forEach(cb, arg) {

        forOf(this.values(), val => {

            cb.call(arg, val, val, this);

        })

    }

    keys() {

        return new Iterator(this.value);

    }



    values() {

        return this.keys();

    }

    entries() {

        return new Iterator(this.value, (value) => [value, value])

    }

    [Symbol.iterable]() {

        return this.values();

    }

}

10.ES6 中 Symbol 如何使用,用在什么地方?

Symbol无法使用new来调用,Symbol()每次执行都可以产生一个唯一的值(基本数据类型),类似于字符串的值

例:

    let s1=Symbol();

    let s2="name";

    let obj={

        [s1]:"terry",   //神秘的唯一值:"terry"

        [s2]:"tom",     //name:"tom"

        s3:"jacky"      //s3:"jacky"

    }

    obj[s1]

    obj[s2]

    obj.s3

    1.Symbol()函数:用来产生唯一值

    2.Symbol(flag):flag字符串,表示标识。生成具有标识的Symbol值

    3.消除魔术字符串

    4.Object.getOwnPropertySymbols:获取某个对象中所有的symbol属性名

      Reflect.ownKeys():获取所有类型的键名,包括常规键名和Symbol键名

    5.Symbol重复利用

      Symbol.for()  缓存

      Symbol.keyFor()

    6.系统内置Symbol方法

      1)Symbol.hasInstance

         所有的构造函数都内置这个方法,当instanceOf的时候会调用

      2)Symbol.iterator

         当迭代对象的时候会被调用 for-of

11.谈谈var、let、const的区别

 1)var

        1.重复声明

        2.变量的提升

            console.log(d);//undefined

            var d;

        3.没有局部作用域

 2)let

        1.不可重复声明

        2.不存在变量提升

        3.有局部作用域

 3)const

        常量,只能赋值一次的变量,其他与let保持相同特性

  1. const定义的基本数据类型的变量不能修改

         const b = 3;

         b++;  //error!

  1. const定义的引用数据类型的变量,const仅保证指针不发生改变,

修改对象的属性不会改变对象的指针,所以是被允许的。

         const obj={age:1};

         obj.age=2;//2

12.如何实现数组去重?[尽可能多方案]

方案一:

 let arr=[1,2,3,1,2,3];

 let result=[...new Set(arr)];

方案二:

     var arr = [3, 2, 6, 7, 5, 3, 2, 7, 4, 4, 8, 9];

        var a = [];

        for (var i = 0; i < arr.length; i++) {

            if (a.indexOf(arr[i]) == -1) {

                a.push(arr[i]);

            }

        }

        console.log(a);

13.如何实现对象深拷贝?

解构赋值:

var obj={name:"terry",age:12,gender:"male"}

    let {...o}=obj;

    o//{name:"terry",age:12,gender:"male"}

o===obj;//false  深拷贝 不改变原值

14.简述Promise.all()、Promise.race()、Promise.allSettled()、Promise.resolve()、Promise.reject()

1.Promise.all([p1,p2,...])

  该方法返回值为Promise,当p1,p2,...全部执行完毕并且状态resolved的时候,Promise的then才会被调用,该then的回调函数的参数是p1,p2,...的运行结果

2.Promise.race(iterable)

  返回值为Promise,返回先改变状态的Promise结果

3.Promise.allSettled(iterable)

  返回值为Promise,与all不同,当所有的承诺对象状态被确认的时候会执行Promise的then,then的参数为结果

4.Promise.resolve(val)

  直接返回一个承诺对象,并且状态为成功

  new Promise(resolve=>{

      resolve(val);

  })

5.Promise.reject(error)

  直接返回一个承诺对象,并且状态为失败

  new Promise((resolve,reject)=>{

      reject(error);

  })

15.ES6中哪些对象是可迭代的?

ES6可迭代的对象:Array,String,Set,Map

实例对象可以直接访问Symbol.iterator,构造函数实现了Symbol.iterator

16.创建一个ArrayLike类,在该类的构造函数中完成数组到类数组对象的转换,并且为其提供迭代器

class ArrayLike {

    constructor(args) {

        for (let i = 0; i < args.length; i++) {

            let val = args[i];

            this[i] = val;

        }

        //定义内部属性length

        Object.defineProperty(this, "length", {

            configurable: true,

            enumerable: false,

            value: args.length

        })

    }

    //手动实现一个类数组构造函数,并且该构造函数实现了Symbol.iterator接口

    //请你实现迭代函数

    *[Symbol.iterator]() {

        for (let k in this) {

            let v = this[k];

            let index = parseInt(v)//为什么value赋给index

            yield { value: v, done: index < this.length ? false : true }

        }

    }

}

let arr = new ArrayLike(["terry", "larry", "tom", "jacky"]);

console.log(arr);//ArrayLike { '0': 'terry', '1': 'larry', '2': 'tom', '3': 'jacky' }



for (let a of arr) {

    console.log(a);

}

// { value: 'terry', done: true }

// { value: 'larry', done: true }

// { value: 'tom', done: true }

// { value: 'jacky', done: true }

17.ES6中如何创建一个静态方法?静态方法中是否可以访问成员属性,为什么?

//创建一个静态方法

static sayNum() {

        // 静态方法只能访问静态属性

        console.log(this.num);

        // console.log(this.name);

}

静态方法只能访问静态属性

因为静态方法是属于整个类的,而非静态方法只能通过对象调用,非静态变量只在属于某个对象时有值,而属于类时是空的,所以不能调用。

18.ES6中如何完成类的继承,super的作用是什么?

// 继承

class Dog extends Animal {

    gender;

    constructor(name, age, gender) {

        super(name, age);

        this.gender = gender;

    }

    sayGender() {

        console.log("my gender is", this.gender);

    }

}

super的作用:在 constructor ⽅法中调⽤ super⽅法继承父类的属性,否则新建实例时会报错。⽗类的静态⽅法,也会被⼦类继承

19.什么是异步函数?异步函数如何使用?

同步就是一件事一件事的执行。只有前一个任务执行完毕,才能执行后一个任务。

异步(async)是相对于同步(sync)而言的。

1.setTimeout就是一个异步任务,当JS引擎顺序执行到setTimeout的时候发现他是个异步任务,则会把这个任务挂起,继续执行后面的代码。直到1000ms后,回调函数cbFn才会执行,这就是异步

2.ajax就是异步的JavaScript和HTML

使用:回调函数是异步操作最基本的方法。

20.ES6中代理是什么?如何使用?请说出至少三个常见的代理方法

代理Proxy

    1.对象 set/get

        let obj={}; //目标对象

        let proxy=new Proxy(obj,{   //代理

            set(target,key,val){

                target[key]=val;

            },

            get(target,key){

                return target[key];

            }

        })

        proxy.name='terry'; //面向代理使用

    2.函数 apply

        let foo=function(msg){console.log(msg);}

        let proxy=new Proxy(foo,{

            apply(target,that,args){    //that指代this(关键字)?     args数组

                target.apply(that,args)

            }

        })

    3.构造函数 constructor

        let Person=function(name){this.name=name}

        let proxy=new Proxy(Person,{

            constructor(target,args){

                return new target(...args)

            }

        })

21.ES6中反射是什么?如何使用?请说出至少三个常见的反射方法

反射Reflect

1.对象 set/get

        let obj={}; //目标对象

        let proxy=new Proxy(obj,{   //代理

            set(target,key,val){

                return Reflect.set(target, key, value)            

},

            get(target,key){

                return Reflect.get(target, key)

            }

        })

        proxy.name='terry'; //面向代理使用

    2.函数 apply

        let foo=function(msg){console.log(msg);}

        let proxy=new Proxy(foo,{

            apply(target,that,args){    //that指代this(关键字)?     args数组

                Reflect.apply(target, that, args);

            }

        })

    3.构造函数 constructor

        let Person=function(name){this.name=name}

        let proxy=new Proxy(Person,{

            constructor(target,args){

                return Reflect.constructor(target, args);

            }

        })

22.简述Typescript与Javascript的区别与关联?

区别:1)es6是弱类型语言(一个变量的数据类型取决于值,数据类型可以改变)

  2)ts添加了强类型特性(一个变量的数据类型在声明的时候确定,变量的数据类型一旦确定无法修改)

联系:Typescript是JavaScript超集

ts = es6 + 强类型

Typescript在JavaScript基础上增加了enum 枚举类型

23.什么是抽象类?抽象类应用在什么场景中?

抽象类:

如果一个类中出现了抽象方法,那么这个类一定是抽象类;

抽象类无法实例化,存在的意义是为了让其他子类继承

(当然抽象类中可以没有抽象方法)

应用场景:

//抽象类

abstract class Parent {

    abstract study(): string;

    eat() {

        console.log("哎真香~");

    }

    work() {

        console.log("工作");

    }

}



class Child extends Parent {

    study(): string {

        super.eat();

        super.work();

        return "好好学习,找到了工作~";

    }

}

24.什么是接口?接口应用在什么场景中?如何实现接口的实现?

接口:抽象到极致的抽象类

    接口中的方法全部都是抽象方法,这些方法无需再使用abstract来修饰

接口是一种特殊的类,子类不再通过extends来继承,而是通过implements来实现

//接口

class User {

    id: number;

    name: string;

    gender: string;

    constructor(id: number, name: string, gender: string) {

        this.id = id;

        this.name = name;

        this.gender = gender;

    }

}

//老板

interface IBaseService {

    foo(): void;

}

//副总

interface IUserService {

    login(username: string, password: number): User;

    register(user: User): void;

}

//经理

class UserServiceImpl implements IBaseService, IUserService {

    foo(): void {



    }

    login(uesrname: string, password: number): User {

        return new User(1, "terry", "male")

    }

    register(user: User): void {



    }

}

25.什么是枚举?

enum 枚举类型

enum Gender {

    MALE = 1,

    FEMALE

}

console.log(Gender.MALE);//1

console.log(Gender.FEMALE);//2

console.log(Gender[1]);//MALE

console.log(Gender[2]);//FEMALE

26.什么是多态?

多态字面意思多种状态,指的是不同的对象按照统一接口执行时,产生多种不同的结果即同一个实现接口,使用不同的实例而执行不同的操作。

⽗类类型的引⽤【dog:Animal】指向的是⼀个⼦类对象【new Animal】,通过该引⽤调⽤say⽅法,依旧执⾏的是⼦类的函数的特点。此外通过⽗类类型引用

class Animal {

    say(): void {

        console.log('动物叫声');

    }

}

class Dog {

    say(): void {

        console.log('旺旺');

    }

    watch(): void {

        console.log('警戒!');

    }

}

let dog: Animal = new Animal();

dog.say(); // 旺旺

dog.watch(); //无法访问!

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值