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

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. UVA 11796 - Dog Distance 向量的应用

    http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&p ...

  2. zookeeper分布式协调服务的使用一

    Zookeeper是一个高性能,分布式的应用协调服务. 提供服务: 1.集群成员的管理(Group Membership) 2.分布式锁(Locking) 3.选主(Leader Election) ...

  3. ehcache、memcache、redis三大缓存比较(转)

    最近项目组有用到这三个缓存,去各自的官方看了下,觉得还真的各有千秋!今天特意归纳下各个缓存的优缺点,仅供参考!  Ehcache 在Java项目广泛的使用.它是一个开源的.设计于提高在数据从RDBMS ...

  4. 【BZOJ 2119】股市的预测

    [链接]h在这里写链接 [题意]     给你一个长度为n的数组a[]     设b[i] = a[i+1]-a[i];     然后让你在b[i]里面找ABA的形式.     这里B的长度要求为m; ...

  5. [Node] Catch error for async await

    When we try to do MongoDB opration, mongoose return Promise, we can use async/await to simply the co ...

  6. HDU 1408 盐水的故事 数学水题

    http://acm.hdu.edu.cn/showproblem.php?pid=1408 题目: 挂盐水的时候,如果滴起来有规律,先是滴一滴,停一下:然后滴二滴,停一下:再滴三滴,停一下...,现 ...

  7. 使用Perl脚本编译Latex

    使用Perl脚本编译Latex 脚本能实现Latex文本的初级编译,并将生成的中间文件移动到同一个目录 调用方法 chmod +x xelatex2pdf.pl xelatex2pdf.pl -n 2 ...

  8. Python数据结构之树

    二叉树 嵌套列表方式 # coding:utf-8 # 列表嵌套法 def BinaryTree(r): return [r, [], []] def insertLeft(root, newBran ...

  9. CompletionService 和ExecutorService的区别和用法

    JavaSE5的Java.util.concurrent包中的执行器(Executor)将为你管理Thread对象,从而简化了并发编程.Executor在客户端和执行任务之间提供了一个间接层,Exec ...

  10. c++ 成员函数指针

    C++中,成员指针是最为复杂的语法结构.但在事件驱动和多线程应用中被广泛用于调用回叫函数.在多线程应用中,每个线程都通过指向成员函数的指针来调用该函数.在这样的应用中,如果不用成员指针,编程是非常困难 ...