Faicso函数问题——JS作用域,原型链,变量提升

本文通过一道JavaScript面试题,深入探讨了JS的作用域、原型链以及变量提升。Faicso函数的调用展示了函数、实例及原型上的方法优先级。变量提升导致getName()输出'互动',而非'商城'。理解这些概念对于前端开发者至关重要。
摘要由CSDN通过智能技术生成

Faicso函数问题——JS作用域,原型链,变量提升

今天偶然在一个web前端交流群中看到了一道群友分享的JavaScript面试题,感觉有点意思,在此分享下。
本文仅个人观点,欢迎各位前辈或者小伙伴批评指正错误,十分感谢!!

题目:

function Faicso() {
      getName = function () { console.log('图片') }
      return this
    }
    Faicso.getName = function () { console.log('微传单')}
    Faicso.prototype.getName = function () {console.log('建站')}
    var getName = function () {console.log('互动')}
    function getName() {console.log('商城')}
    // 说说下面的输出情况
	Faicso.getName()
	getName()
	Faicso().getName()
	getName() 
	new Faicso.getName() 
	new Faicso().getName()
	new new Faicso().getName()

这道题的执行顺序很有讲究,若是将这七个执行顺序调换一下,结果很可能会不同。

输出结果:

	Faicso.getName()//微传单                
    getName()// 互动                        
    Faicso().getName() // 图片              相当于 window.getName()  但是若是在这里写成 window.getName()或 this.getName() 将返回 '互动'的getName函数
    getName() // 图片
    new Faicso.getName() // 微传单
    new Faicso().getName()// 建站
    new new Faicso().getName() // 建站

答案步步详解

	Faicso.getName()
	// 微传单  见题目第五行代码,为Faicso函数添加getName()方法(在JS中函数也是对象,对象则有属性和方法)  
	// 但这里为Faicso函数直接添加的方法只能为其本身使用,不能被 new Faicso() 实例对象使用
	// 要想实例对象也能使用 getName()方法的话,需在 Faicso.prototype 上添加此方法(本题有涉及到)      
    getName()
    // 互动  这里为什么会是'互动',而不是'商城'或'图片'呢?
    // 这里的原因涉及到 变量提升 ,参看下文片段解释1                      
    Faicso().getName() // 图片    
    // 相当于 window.getName() 
    // 但是若是在这里写成 window.getName()或 this.getName() 将返回 '互动'的getName函数
    // 因为这里首先调用 执行了Faicso函数,Faicso函数内部又对全局的getName方法重新赋值为'图片'的函数
    getName() // 图片
    // 因为上一步执行了Faicso函数,为this.getName方法重新赋值为'图片'的函数,所以这里再次调用全局的getName方法就会输出'图片'
    new Faicso.getName() // 微传单
    // 这里new 了一个 Faicso.getName()函数的实例对象,输出同调用 Faicso.getName()
    new Faicso().getName()// 建站
    // 这里就涉及到了上面提到的 new Faicso()实例调用getName()方法
    new new Faicso().getName() // 建站
    // 这里是 创建了一个 Faicso()实例的getName()方法的实例对象
    // 而 Faicso()实例的getName()方法 同上都是继承于Faicso.prototype

片段解释
片段1. getName() // 互动 这里为什么会是’互动’,而不是’商城’或’图片’呢?
// 这里的原因涉及到 变量提升

// 原题目代码
var getName = function () {console.log('互动')}
    function getName() {console.log('商城')}
    
// 相当于 变量提升后的代码
function getName(){console.log('商城')}  // 函数声明提升 (函数声明提升优先于变量声明的提升)
var getName  // 变量声明提升,但赋值未提升
getName = function (){console.log('互动')} // 变量声明提升,但赋值未提升

所以最终 ’ 互动’ 的函数覆盖了 ‘商城’ 的函数。

  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值