这段时间一直在研究设计模式,在看工厂模式的时候,看到一段代码

VehicleFactory.prototype.createVehicle = function ( options ) {

  if( options.vehicleType === "car" ){
this.vehicleClass = Car;
}else{
this.vehicleClass = Truck;
} return new this.vehicleClass( options ); };

  对这段代码最后的返回new this.vehicleClass( options )有些迷惑,到底是先执行了后面的方法还是先new了一个新对象出来呢?

  直到今天v2ex出现一道JS面试题, v2ex链接  前面几问都没问题,到后面涉及到new的时候感觉有些混乱。

function Foo() {
getName = function () { alert (1); };
return this;
}
Foo.getName = function () { alert (2);};
Foo.prototype.getName = function () { alert (3);};
var getName = function () { alert (4);};
function getName() { alert (5);} //请写出以下输出结果:
Foo.getName();
getName();
Foo().getName();
getName();
new Foo.getName();
new Foo().getName();
new new Foo().getName();

找了原文,看了下评论,找到了关键的地方,下面的1与2是原文的评论。

1.其实博主没讲明白,这里确实是(new Foo()).getName(),但是跟括号优先级高于成员访问没关系,实际上这里成员访问的优先级是最高的,因此先执行了 .getName,但是在进行左侧取值的时候, new Foo() 可以理解为两种运算:new 带参数(即 new Foo())和函数调用(即 先 Foo() 取值之后再 new),而 new 带参数的优先级是高于函数调用的,因此先执行了 new Foo(),或得 Foo 类的实例对象,再进行了成员访问 .getName。

2.第五问和第六问关于优先级的解释也不恰当,new Foo()中的括号并不是括号运算符,而是函数调用的一部分
new Foo.getName(); 和 new Foo().getName(); 的区别在于
new Foo 结合属于 new 无参数列表的情况(17级)
new Foo() 结合属于 new 有参数列表的情况(18级)

成员访问运算符(.)优先级为 18 级,和 new Foo() 同级
对于同级运算符,按照从左到右的顺序依次计算
所以先执行 new Foo() 返回一个 Foo 的对象 ,对 Foo 对象调用 getName 时查找引用链,得到 Foo.prototype.getName

new Foo 结合被判定为无参数列表的new,优先级低于成员访问,
所以先执行成员访问得到 Foo 的属性 getName, 然后 Foo.getName 和 new 结合,执行带参数列表的 new 运算

需要注意的是带参数列表的 new ...(...) 看起来像是 new 后面跟了一个函数调用,但在判断运算符优先级时 new 运算是一个整体,不能把它分开
javascript 中设定带参数列表 new 的优先级高于函数调用,那么在满足带参数列表的 new 运算符时,就不存在函数调用了
虽然带参数列表的 new 运算也会执行函数调用,但是在判断运算时不把 new 和 ...(...) 分开。

  v2ex那位楼主对这个问题的解析也很不错,可以看一下。现在对开头的工厂模式那个new有了正确理解了吧。

new与属性访问的顺序,从一道JS面试题说起的更多相关文章

  1. 一道JS面试题引发的血案

    刚入职新公司,属于公司萌新一枚,一天下午对着屏幕看代码架构时. BI项目组长给我看了一道面试别人的JS面试题. 虽然答对了,但把理由说错了,照样不及格. 话不多说,直接上题: var a = 1; s ...

  2. 一道JS面试题所引发的"血案",透过现象寻本质,再从本质看现象

    觉得本人写的不算很烂的话,可以登录关注一下我的GitHub博客,新手写东西写的不好之处,还望见谅,毕竟水平有限,写东西只为交流提高,一起学习,还望大神多加指点,指出纰漏,和提出宝贵的意见,博客会坚持写 ...

  3. 腾讯的一道js面试题(原型)

    有一只小狗叫花花,它会“汪汪”叫,他的同伴也会汪汪叫,后来环境发生了变化,新出生的狗不会再“汪汪”叫,而变成“呜呜”叫. 试通过继承来达到目的 function Dog(){ 2 this.bark ...

  4. 一道js面试题看变量的作用域

    [问题]分别求下面程序的输出结果: 1. <script type="text/javascript"> var a = 10; sayHi(); function s ...

  5. 一道js面试题

     当然这道面试题并不一定就能在你面试的时候遇到,但是不怕一万就怕万一,会的多一些还是好的. 问:怎么判断一串字符中哪个字符出现的最多,最多几次或者这串字符分别有哪些,每个字符出现了几次.写你请出运算代 ...

  6. 关于一道JS面试题的思考

    题目: ; i < ; i++) { setTimeout(function() { console.log(new Date, i); }, ); } console.log(new Date ...

  7. 一道经典的js面试题

    # 声明:学习编程语言最好的方式就是通过实例学习 ## 下面是我在博客上看到的一道js面试题,可以说非常经典,下面会以最简单的方式让你理解题目:```bashfunction Foo() { getN ...

  8. 一道经典JS面试题

    超过80%的候选人对下面这道JS面试题的回答情况连及格都达不到.这究竟是怎样神奇的一道JS面试题?他考察了候选人的哪些能力?对正在读本文的你有什么启示? 不起眼的开始 招聘前端工程师,尤其是中高级前端 ...

  9. javascript属性访问表达式

    属性访问表达式运算得到一个对象属性或一个数组元素的值.js为属性访问定义了2中语法: expression.identifier expression["expression"] ...

随机推荐

  1. JS错误记录 - 按左右箭头div移动、一串div跟着鼠标移动

    本次练习错误总结: 1. div跟着用户操作而移动,首先必须要绝对定位,否则无法移动. 2. if条件语句里面是双等号,不是单等号(赋值). 3. 坐标值没有Right,只能offsetLeft 加减 ...

  2. 【Codeforces Round #445 (Div. 2) A】ACM ICPC

    [链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 三重循环 [代码] #include <bits/stdc++.h> using namespace std; int ...

  3. uva 10710 - Chinese Shuffle(完美洗牌)

    option=com_onlinejudge&Itemid=8&category=474&page=show_problem&problem=1651"> ...

  4. POJ 1275 Cashier Employment 挺难的差分约束题

    http://poj.org/problem?id=1275 题目大意: 一商店二十四小时营业,但每个时间段需求的雇员数不同(已知,设为R[i]),现有n个人申请这份工作,其可以从固定时间t连续工作八 ...

  5. LA 3882 - And Then There Was One(约瑟夫 递归)

    看题传送门 题目大意: N个数排成一圈,第一次删除m,以后每k个数删除一次,求最后一被删除的数. 如果这题用链表或者数组模拟整个过程的话,时间复杂度都将高达O(nk),而n<=10000,k&l ...

  6. radare, the reverse engineering framework

    History The radare project [http://radare.org/] started in February of 2006 aiming to provide a free ...

  7. POJ 3086 Triangular Sums (ZOJ 2773)

    http://poj.org/problem?id=3086 http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=1773 让你计算两 ...

  8. 微服务API模拟框架frock介绍

    本文来源于我在InfoQ中文站翻译的文章,原文地址是:http://www.infoq.com/cn/news/2016/02/introducing-frock Urban Airship是一家帮助 ...

  9. Python 细节与基础拾遗

    locals():当前环境下的全部局部变量,字典(dict)类型,所有的 key 均为字符串类型: if 'sess' in locals() and sess is not None: print( ...

  10. [Elm] Installing and setting up Elm

    Before writing any Elm we need to first install the runtime locally. In this lesson we install the E ...