这段神奇代码很有意思

网友投稿 811 2022-05-30

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

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

能不能搞点阳间的代码 !

指定有什么大病

哪个人才写出这样的代码

//第一块 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

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

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两块代码来讲

var getName = function() { console.log(4); } function getName() { console.log(5); }

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

第一步:创建一个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

function Foo() { getName = function() { console.log(1); } return this }

第四个

getName()输出1

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

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关键字

创建一个空对象

空对象的继承构造函数的原型

让this指向构造函数的对象实例,执行构造函数内容为新对象添加属性和方法

返回this

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

第七个

终于到最后一个了

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

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

终于!!

这段神奇的代码很有意思

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

JavaScript 面向对象编程

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:Python中的惊喜彩蛋
下一篇:【RecyclerView】 九、为 RecyclerView 设置不同的布局样式
相关文章