美文网首页
面试题【Day11】

面试题【Day11】

作者: 小王子__ | 来源:发表于2021-09-06 17:20 被阅读0次

    本篇绪论

    1, 宏任务、微任务

    2,创建对象

    3,instanceof

    1, 宏任务、微任务

    JS是单线程执行的语言,在同一时间内只能做一件事情。这就导致后面的任务需要等到前面的任务完成才能执行,如果前面的任务很耗时就会造成后面的任务一直等待。为了解决这个问题JS出现了同步任务和异步任务。

    同步任务:在主线程上排队执行的任务只有前一个任务执行完毕,才能执行后一个任务,形成一个执行栈

    异步任务:不进入主线程,而是进入任务队列,当主线程中的任务执行完毕,就从任务队列中取出任务放进主线程中进行执行。由于主线程不断重复的获取任务、执行任务、再获取再执行...,所以这种机制被叫做事件循环(Event Loop)

    任务队列中又分为宏任务、微任务

    console.log(1)
    setTimeout(_ => {
      console.log(2)
    }, 0)
    Promise.resolve().then(res => {
      console.log(3)
    })  // 1 3 2
    

    常见的微任务:Promise、process.nextTick、MutationObserver

    常见的宏任务: script、setTimeout、setInterval、setImmediate

    Event loop执行顺序:

    先执行宏任务script,并执行里面的同步任务,执行栈为空后查询是否存在微任务,存在立即执行,然后开始下一轮的事件循环。

    定时器

    定时器:超时定时器setTimeout,间歇调用定时器setInterval

    定时器是宏任务,在定时器计时完毕后会将它的回调函数加入到任务队列中,等待下一次的事件循环。也就是说下一次执行的定时器是回调函数,计时已经在定时器模版中完成了。

    promise
    setTimeout(_ => {
      console.log(1)
    }, 0)
    new Promise(resolve => {
      console.log(2)
      resolve()
    })
    .then(_ => {
      console.log(3)
    })
    console.log(4)
    // 2 4 3 1
    

    2,创建对象

    JS对每个创建的对象都会设置一个原型,指向它的原型对象。

    当我们访问一个对象的属性时(obj.xxx),JS引擎会在当前对象上找该属性,如果没找到,会去其原型对象上找,如果还找不到就一直上溯到Object.prototype对象,最后还是没找到就只能返回undefined了。

    // 创建一个Array对象
    const arr = [1,2,3,4,5]
    

    其原型链:

    arr ----> Array.prototype ----> Object.prototype ----> null
    
    // 创建一个函数对象
    function fn () {return 1}
    

    其原型链:

    fn ----> Function.prototype ----> Object.prototype ----> null
    

    构造函数方法创建对象

    function Student(name) {
      this.name = name;
      this.hello = function () {
        console.log('Hello, ' + this.name + '!')
      }
    }
    

    这是一个普通的函数,但是在js中,可以用关键字new来调用这个函数,并返回一个对象

    const p1 = new Student('xiaowang')
    console.log(p1) 
    console.log(p1.hello())
    
    image

    如果不new,这就是一个普通函数,它返回undefined,如果写了new它就是一个构造函数,它绑定的this指向新创建的对象,并默认返回this,也就是说,不需要在最后写return this

    新创建的p1的原型链:

    p1 ----> Student.prototype ----> Object.prototype ----> null
    

    也就是说,p1的原型指向Student的原型

    用new Student()创建的对象还从原型上获得了一个constructor属性,它指向函数Student本身

    console.log(p1.constructor === Student.prototype.constructor)  // true
    console.log(Student.prototype.constructor === Student) // true
    console.log(p1 instanceof Student) // true
    console.log(Object.getPrototypeOf(p1) === Student.prototype)  // true
    // getPrototypeOf用来获取p1对象的原型对象
    

    Student.prototype指向的对象就是p1的原型对象,这个原型对象自己还有个属性constructor,指向Student本身。

    函数Student有个属性prototype指向p1的原型对象,但是p1对象没有prototype这个属性,不过可以用proto这个非标准用法来查看

    我们认为p1对象继承Student

    const p1 = new Student('p1')
    const p2 = new Student('p2')
    console.log(p1.hello === p2.hello)  // false
    

    p1和p2各自的hello是一个函数,但是它们是两个不同的函数,虽然函数名称和代码都是相同的

    如果我们通过new Student创建了很多对象,这些对象的hello函数实际上只需要共享同一个函数就可以了,这样可以节省很多内存。

    function Student(name) {
      this.name = name
    }
    Student.prototype.hello = function () {
      console.log(this.name)
    }
    const p1 = new Student('p1')
    const p2 = new Student('p2')
    console.log(p1.hello === p2.hello)  // true
    

    3,instanceof

    instanceof用于判断引用类型属于哪个构造函数的方法。

    const arr = []
    arr instanceof Array // true
    typeof arr // object
    

    instanceof可以在继承关系中用来判断一个实例是否属于它的父类型

    function Aoo(){} 
    function Foo(){} 
    Foo.prototype = new Aoo() //JavaScript 原型继承
    var foo = new Foo()
    console.log(foo instanceof Foo) 
    console.log(foo instanceof Aoo)
    

    foo instanceof Foo的判断逻辑:foo的proto一层一层往上,是否对应到Foo.prototype,再往上,看是否对应着Aoo.prototype,再试着判断 foo instanceof Object

    即instanceof可以用来判断多层继承关系

    相关文章

      网友评论

          本文标题:面试题【Day11】

          本文链接:https://www.haomeiwen.com/subject/ubfywltx.html