美图笔试题(输出问题)

7 篇文章 0 订阅

在这里插入图片描述

function Foo() {
      getName = function () {
        console.log(1)
      }
      return this
}
Foo.getName = function () {
      console.log(2)
}
Foo.prototype.getName = function () {
      console.log(3)
}
var getName = function () {
      console.log(4)
}
function getName() {
      console.log(5)
}

Foo.getName() //2
getName() //4
Foo().getName() //1
getName() //1
new Foo.getName() //2
new Foo().getName() //3
new new Foo().getName() //3

下面来认真分析一波上面的代码:

  • Foo.getName() //2
    这个没什么问题,因为里面的getName不属于实例化也不属于函数的

  • getName() //4 这是因为赋值式函数(var getName = function)是不会提升的,但是声明式函数(function getName)会。这样会导致赋值式函数覆盖声明式函数。结果调用的是

var getName = function () {
      console.log(4)
    }
验证一下
fn()//1
var fn = function () {
      console.log(2)
}
fn()//2
function fn() {
      console.log(1)
}
fn() //2

第一个输出1,这是因为function fn函数提升,而var fn = function不会提升
第二个输出2,这是因为在var fn = function下面执行,此时已经将function fn覆盖了
第三个输出2,同理

  • Foo().getName() //1
    执行了Foo(),但是输出1并不是调用了getName,里面的getName并不是这样调用的,而是因为return了this,此时this明显是window,注意Foo函数里的Foo并不是用var来定义的,正如上次小熊说的,没有用let/var/const定义的变量是没有函数作用域的,所以此时的getName为全局作用域的函数,Foo().getName()即相当于window.getName(),因为执行了Foo()相当于把这个getName激活了,覆盖了原来了全局的getName,即输出1

  • getName() //4
    因为执行了Foo()相当于把这个getName激活了,覆盖了原来了全局的getName,即输出1

  • new Foo.getName() //2
    相当于执行了一遍 Foo.getName(),当然是执行2啦

  • new Foo().getName() //3
    此时相当于new Foo()后再执行getName方法,此时为啥不执行console.log(2)呢,是因为实例的proto指向构造函数prototype

  • new new Foo().getName() //3
    这个表达式相当于先new Foo()
    再new (new Foo()).getName()

类似于:

let ans = new Foo()
let tem = new ans.getName()

new一个实例的getName,也就是在prototype里找getName,当然执行console.log(3)

经过上述可以发现,new都会找第一个的能new的函数,直到找到函数为止。找到了就是执行实例化的函数,如果没找到就报错。如果再加一个new,按照规则,继续new一个new过的实例化的函数的对象

上面提到了,里面的getName并不是这样调用的,举例:

function Goo() {
      getGoo = function () {
        console.log(1)
      }
    }
    console.log(Goo().getGoo())//demo.html:48 Uncaught TypeError: Cannot read property 'getGoo' of undefined
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值