周一了打工人,今天来看看这道原型链的题怎么做

332 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第6天,点击查看活动详情

目录

今日题

  1. 题目
  2. 分析 昨日题
  3. 题目
  4. 答案
  5. 解析 结语

今日题

题目

function F() {}
var f=new F()
Object.prototype.a='鲨鱼辣椒'
Function.prototype.b='蝎子莱莱'
console.log(f.a)
console.log(f.b)
console.log(F.a)
console.log(F.b)

分析

大致看一下代码——prototype,想必已经知道了今天又是与原型相爱相杀的一天。简单分析一下代码,有一个函数F,函数F中并无任何实质性代码,随后通过new调用该函数,此操作会使f成为构造函数F的实例对象,所以我们可以得到f.__proto__ === F.prototype这一重要关系,其实无论原型的题怎么出、怎么变化,我感觉只要掌握了这一重要关系之后,就像令狐冲领悟了独孤九剑,永远能够无招胜有招;接下来便是在Object的原型对象上添加了一个属性a,其值为'鲨鱼辣椒',又在Function的原型对象上添加了一个属性b,其值为'蝎子莱莱',其实代码执行到这里我们已经有了大致的思路了,只要知道__proto__这条线最终会指向哪里,我相信下面的四个console.log是难不倒我们的。前两个console.log只需要知道f.__proto__ === F.prototype这一层关系,然后顺着原型链慢慢找就行了;而后两个console.log我们则需要知道所有函数都是大写Function的实例,而实例对象的隐式原型指向构造函数的显式原型,再明白这一层关系后,今天的题绝对是手到擒来了。

昨日题

题目

for(var i = 0; i < 5; i++) {
    (function(i) {
        setTimeout(function() {
            console.log(i);
        }, 1000);
    })(i)
}

答案

0,1,2,3,4

解析

for循环从0循环至4(i<5),总共循环五次,产生了五个匿名函数,而匿名函数在自调用时,会将每次for循环中的循环变量i传递进去,匿名函数使用形参i来接收循环变量i。每次匿名函数自调用时,都会产生一个定时器,而定时器的职责就是打印变量i,这个被打印的变量i是匿名函数通过闭包存下来的每次的循环变量i,所以说每个匿名函数中的i都不相同,所以打印时为0,1,2,3,4,而不是5,5,5,5,5。如果我们这道题把匿名函数的实参i和形参i全部去掉,那么这道题就会输出5,5,5,5,5了,这是因为在执行setTimeout打印i时,在匿名函数这个作用域中找不到变量i,根据作用域的特性它需要往上找,而在全局中是存在变量i的,所以打印变量i,需要注意的是,在执行setTimeout时,for循环早已执行完毕,所以每次的i都会打印5

结语

此文章已收录至《JavaScript每日一题》专栏,如果你对本专栏有任何建议,欢迎反馈。如果你对此文章中的题目还有不懂的地方,那么请在评论区留言与大家一起讨论吧。
创作不易,少年,就请留个赞再走吧!