前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >这段代码很有意思!

这段代码很有意思!

作者头像
小丞同学
发布2021-08-16 15:52:42
4940
发布2021-08-16 15:52:42
举报
文章被收录于专栏:小丞前端库

这段代码很有意思!

当你看到这段代码时,你的心情是怎样的呢!

这是几个同学给我的答复,嗯,就很好

能不能搞点阳间的代码 !

指定有什么大病

哪个人才写出这样的代码

在这里插入图片描述
在这里插入图片描述
代码语言:javascript
复制
//第一块
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();

getName();

Foo().getName();

getName();

new Foo.getName();

new Foo().getName();

new new Foo().getName();

作为菜鸟的我,在面试的时候,看到了这阴间代码,心里想着谁无聊写这样的代码呀,屁点用没有,却只能默默的分析题目,但最终还是错了几个,回来之后又好好分析了一下,其实也不是很难,只是在面试的时候看到这样的东西,实在是有点搞心态了!

在这里插入图片描述
在这里插入图片描述

大家可以先自己尝试写一下这道题

下面我们来一个一个的分析它

一下是本菜鸟的小题解,有什么错误的地方欢迎大家指出,共同进步!!!!

第一个

Foo.getName()输出2

第一个并不难,主要和一二,两块代码有关

代码语言:javascript
复制
function Foo() {
    getName = function() {
        console.log(1);
    }
    return this
}

Foo.getName = function() {
    console.log(2);
}

其实这前面的只是一个迷惑作用,给函数直接添加属性和方法,实际上是可以的,因为函数也是对象,但是和数组一样,不会改变原先属性的值,也就是Foo.getName是给Foo对象下添加一个属性,值是一个函数,和Foo函数下的getName是不影响的,所以Foo.getName()实际上是访问Foo对象下的getName输出2

第二个

getName()输出4

这个考察的是预编译的知识,直接执行了getName,这里就摘取4,5两块代码来讲

代码语言:javascript
复制
var getName = function() {
    console.log(4);
}
function getName() {
    console.log(5);
}

在预编译的过程中会经历以下几步

代码语言:javascript
复制
第一步:创建一个Go对象,因为这里是在全局下
Go {}
第二步:找形参和变量声明,值给undefined
Go {
	getName:undefined;
}
第三步:实参形参统一,这里没有形参
Go {
	getName:undefined
}
第四步:找函数声明,值赋予函数体
Go {
	getName:getName();
}

当预编译执行完成后,才开始执行代码,也就是那条函数表达式,getName被赋予了新的函数体,也就是输出4

第三个

Foo().getName()输出1

Foo()先执行,全局下的getName被重新赋值,返回了一个this,这里的this指向的是window,此时的getName实际上是window.getName也就是输出1

代码语言:javascript
复制
function Foo() {
    getName = function() {
        console.log(1);
    }
    return this
}

第四个

getName()输出1

因为在执行上一个函数时,由于getName是定义在全局的,所以在执行时,实际上改变了全局作用域下的getName的值,所以再次执行getName(),输出的是1

代码语言:javascript
复制
function Foo() {
    getName = function() {//在执行上一条语句时,改变了全局变量的值
        console.log(1);
    }
    return this
}
//这里声明了变量getName,为全局变量
var getName = function() {
    console.log(4);
}

第五个

new Foo.getName()输出

在做这道题之前需要知道,运算符的优先级,这是从MDN文档上的截图,可以看到成员访问运算符的优先级大于new一个无参列表的有限级,也就是new Foo.getName()实际上是new (Foo.getName()),括号内输出2

new Foo属于new无参数列表

在这里插入图片描述
在这里插入图片描述

第六个

new Foo().getName()输出 3

相当于执行(new Foo()).getName()

new Foo()实例化了Foo这个构造函数,返回的是继承有Foo()原型的新对象,在执行getName()时,由于新对象下没有这个方法,会沿着原型链上寻找,能够在原型上找到并输出3

new关键字

  1. 创建一个空对象
  2. 空对象的继承构造函数的原型
  3. 让this指向构造函数的对象实例,执行构造函数内容为新对象添加属性和方法
  4. 返回this
代码语言:javascript
复制
Foo.prototype.getName = function() {
    console.log(3);
}

第七个

终于到最后一个了

new new Foo().getName()输出 3

相当于执行new (new Foo().getName())先执行括号里的,也就是上一题的,也就是输出3


终于!!

其实写完感觉也不是很难,思路清晰,不要乱套还是可以拿下的,希望大家在碰到这种阴间代码时,能够把它妥妥拿下!!

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2021/04/10 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 这段代码很有意思!
    • 下面我们来一个一个的分析它
    领券
    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档