new new Foo().getName()面试题解析
经典面试题 Foo().getName() 解析
题目如下,写出输出内容(注释:abcde为步骤标号,便于下边分析定位)
// a.
function Foo () {getName = function () {console.log(1);}return this;
}
// b.
Foo.getName = function () {console.log(2);
}
// c.
Foo.prototype.getName = function () {console.log(3);
}
// d.
var getName = function () {console.log(4);
}
// e.
function getName () {console.log(5);
}Foo.getName();
getName();
Foo().getName();
getName();
new Foo.getName();
new Foo().getName();
new new Foo().getName();
解析:
1. Foo.getName(); // 2
Foo为一个函数对象,对象都可以有属性,题目 b 处定义Foo的getName属性为函数,输出2
2. getName(); // 4
这里看d、e处,d为函数表达式,e为函数声明,两者区别在于变量提升,这两处可以等价于
var getName = undefined;
// e处提升到顶部
getName = function () {console.log(5);
}...
// d. 重新赋值
getName = function () {console.log(4);
}
// e....
可见函数声明的 5 会被后边函数表达式的 4 覆盖。
3. Foo().getName(); // 1
这里要看a处,在Foo内部将全局的getName重新赋值为 console.log(1) 的函数,执行Foo()返回 this,这个this指向window,Foo().getName() 即为window.getName(),输出 1。
4. getName(); // 1
上述3中,全局的getName已经被重新赋值,所以这里依然输出 1。
5. new Foo.getName(); // 2
这里等价于 new (Foo.getName()),先执行 Foo.getName(),输出 2,然后new一个实例;
6. new Foo().getName(); // 3
这里等价于 (new Foo()).getName(), 先new一个Foo的实例,再执行这个实例的getName方法,但是这个实例本身没有这个方法,所以去原型链__protot__上边找,实例.__protot__ === Foo.prototype,所以输出 3。
7. new new Foo().getName(); // 3
这里等价于new (new Foo().getName()),如上述6,先输出 3,然后new 一个 new Foo().getName() 的实例。
补充:
关于上述 5中 new Foo.getName()先执行 Foo.getName(),而6中 new Foo().getName() 先执行 new Foo(),是因为:
- new Foo() 属于new(带参数列表)
- new Foo属于new(无参数列表)
无参数列表的优先级为18,而成员访问的优先级为19,高于无参数列表。因此new Foo.getName()先执行Foo.getName()
带参数列表的优先级为19,而成员访问的优先级也为19,按照运算符规则(同一优先级,按照从左向右的执行顺序),new Foo().getName()先执行new Foo(),再对new之后的实例进行成员访问.getName()操作。
这是js运算符的优先级链接,可查看每个运算符的优先级。
new new Foo().getName()面试题解析相关推荐
- new Foo().getName()经典面试题
一道经典的面试题,下面用a b c d 标注方便讲解 <!DOCTYPE html> <html lang="en"> <head><me ...
- js面试题Foo.getName()的故事
首先声明下:此题是本人面试时笔试题中的一道,回来一搜居然雷同,纯属偶然,特写此篇来整理一下思绪... 原题: function Foo() {getName = function () { conso ...
- JS经典面试题04-原型链Foo.getName
1.1-答案揭晓 1.2-原理解析 <!DOCTYPE html> <html lang="en"><head><meta charset ...
- 网络工程师历年试题解析(PDF文字版)2004-2009
网络工程师历年试题解析(PDF文字 版)2004-2009 转载于:https://www.cnblogs.com/gavinhughhu/archive/2010/04/08/1706929.htm ...
- c# 多线程 执行事件 并发_C#.NET Thread多线程并发编程学习与常见面试题解析-1、Thread使用与控制基础...
前言: 因为平时挺少用到多线程的,写游戏时都在用协程,至于协程那是另一个话题了,除了第一次学习多线程时和以前某个小项目有过就挺少有接触了,最近准备面试又怕被问的深入,所以就赶紧补补多线程基础. 网上已 ...
- 嵌入式linux面试题解析(二)——C语言部分三
嵌入式linux面试题解析(二)--C语言部分三 1.下面的程序会出现什么结果 #include <stdio.h> #include <stdlib.h> #include ...
- linux嵌入式面试题合集,嵌入式linux面试题解析(一)——ARM部分二
嵌入式linux面试题解析(一)--ARM部分二1.描述一下嵌入式基于ROM的运行方式基于RAM的运行方式有什么区别.基于RAM的运行方式:需要把硬盘和其他介质的代码先加载到ram中,加载过程中一般有 ...
- 美团Android开发工程师岗位职能要求,高级面试题+解析
前言 不知道大家面试的时候,有没有遇到这种情况,面试工资谈的是10K,最后干着40K的活!说着冠冕堂皇,提升大家能力的话,做着死命压榨员工,996成了程序员心里的魔咒! 初级安卓开发工程师(10K-1 ...
- C#.NET Thread多线程并发编程学习与常见面试题解析-1、Thread使用与控制基础
前言: 因为平时挺少用到多线程的,写游戏时都在用协程,至于协程那是另一个话题了,除了第一次学习多线程时和以前某个小项目有过就挺少有接触了,最近准备面试又怕被问的深入,所以就赶紧补补多线程基础. 网上已 ...
最新文章
- JAVA求是否为闰年,for-while循环,输出你好
- valgrind——hisi平台valgrind
- SDN — 核心玩家与技术流派
- 将一个对象拆开拼接成URL
- 打开端口_打印机ip及端口设置
- BilibilivideoDownload下载器
- codeforces#320(div2) D Or Game 贪心
- 问题-[Delphi]用LoadLibrary加载DLL时返回0的错误
- idea每次都要配置tomcat_午饭收藏夹里的c位石锅拌饭,每次来到都要等位......
- 用旧电脑安装黑群晖系统
- 输出菱形图案(数字版)
- BIOS三种硬盘模式
- python实现中撤销上一步的代码mac_苹果电脑command+z撤销后如何恢复撤销前的上一步?...
- android qq登录分析,Android第三方登录之QQ登录
- IE可以上网其他浏览器上不了
- [macOS]_[初级]_[关于程序签名时出现User interaction is not allowed的问题]
- 运放芯片哪个最好_老师,请问哪个投影机品牌最好?今天影院君来讲讲这个话题...
- 中国汽车服务行业投资发展策略及运营商机研究报告2021-2027年
- 2019社交电商十大平台集锦
- google推荐系统初探
热门文章
- laravel5.5 sendCloud 发送邮件(sendCloud Api and naux/sendcloud )
- Python - 内置函数详解(截至v3.6.x)
- uni-app 报错getUserProfile:fail can only be invoked by user TAP gesture.
- 黑鲨手机计算机科学技术器,黑鲨4Pro将PC的SSD存储科技带到手机端,真技术革命还假营销噱头?...
- php 发 语音验证码,分享一下子语音验证码的php开发流程
- MQTT入门2 -- “Error: Invalid password hash for user nick.”和“Connection Refused: not authorised.”...
- QlikView处理数据
- QlikView sheet权限
- 一周上手flutter
- linux投影手机,linux连接投影机方法介绍