一道有意思的笔试题引发的对于new操作符的思考
楼主比较喜欢看一些很短但很有意思的题目,无意间又瞥到了一题,大家不妨可以一试。(原题链接猛戳这里)
function Fn1() {
this.name = 'peter';
return {
name: 'jack'
};
}
function Fn2() {
this.name = 'peter';
return 'jack';
}
var obj1 = new Fn1();
var obj2 = new Fn2();
console.log(obj1.name, obj2.name);
或许你经常写面向对象编程的代码,也熟悉以上代码中this的用法甚至是prototype或者原型链,但是还是无法解释上面代码的输出,这时我们不得不承认对new的了解还不是很透彻。
先看一段普通的使用new操作符创建对象的代码:
function Person(a, b) {
this.name = a;
this.age = b;
}
Person.prototype.show = function() {
console.log(this.name, this.age);
};
var p = new Person('hanzichi', 10);
console.log(p);
将console的内容截图:

我们可以清楚看到,p是一个对象,并且拥有构造函数Person中创建的name和age属性,还有个__proto__属性(这货太特殊,反正不在p的hasOwnProperty内!),其值为构造函数的prototype属性值。
其实new操作符创建对象可以分为四个步骤:
- 创建一个空对象
- 将所创建对象的__proto__属性值设成构造函数的prototype属性值
- 执行构造函数中的代码,构造函数中的this指向该对象
- 返回该对象(除非构造函数中返回一个对象)
用代码表示如下:
function Person(a, b) {
this.name = a;
this.age = b;
}
Person.prototype.show = function() {
console.log(this.name, this.age);
};
// var p = new Person('hanzichi', 10);
var p = {};
p.__proto__ = Person.prototype;
Person.call(p, 'hanzichi', 10);
console.log(p);

观察输出的p,我们看到获取的对象p和通过new操作符获取的对象属性以及属性值一致,甚至连p.__proto__通过hasOwnProperty都无法检测到!
通过以上的介绍,我们基本就可以解答本文开头的那个问题了,其实就是构造函数里,如果返回一个非null的对象,则将该对象值赋值给新建的对象,其实上面的实例代码还少了一个是否返回对象的判断,整理后应该是:
function Person(a, b) {
this.name = a;
this.age = b;
return {
name: 'zichi'
};
}
Person.prototype.show = function() {
console.log(this.name, this.age);
};
function init() {
var p = {};
p.__proto__ = Person.prototype;
var temp = Person.call(p, 'hanzichi', 10);
if(temp !== null && typeof temp === 'object')
return temp;
return p;
}
var p = init();
console.log(p);
一道有意思的笔试题引发的对于new操作符的思考的更多相关文章
- 【Android】一道Android OpenGL笔试题
一道Android OpenGL笔试题 SkySeraph May. 5th 2016 Email:skyseraph00@163.com 更多精彩请直接访问SkySeraph个人站点:www.sky ...
- Linux fork函数具体图解-同一时候分析一道腾讯笔试题
原创blog.转载请注明出处 头文件: #include<unistd.h> #include<sys/types.h> 函数原型: pid_t fork( void); (p ...
- 关于 parseInt 的一道有意思的面试题
看完标题,入坑过的同学脑海里很快会浮现出这道经典面试题,没碰到过的同学不妨跟着楼主先来复习一遍 parseInt 的用法(主要参考 MDN). parseInt 是 JavaScript 中的一个全局 ...
- java线程同步问题——由腾讯笔试题引发的风波
刚刚wm问我了一道线程的问题,因为自己一直是coder界里的渣渣.所以就须要恶补一下. 2016年4月2号题目例如以下. import java.util.logging.Handler; /** * ...
- 一道国外前端面试题引发的Coding...
刚刚看到CSDN微信公众号一篇文章,关于国外程序员面试前端遇到的一道测试题,有点意思,遂写了下代码,并记录一下~ 题目是这样的: ['Tokyo', 'London', 'Rome', 'Donlon ...
- 一道面试题引发的对javascript类型转换的思考
最近群里有人发了下面这题:实现一个函数,运算结果可以满足如下预期结果: add(1)(2) // 3 add(1, 2, 3)(10) // 16 add(1)(2)(3)(4)(5) // 15 对 ...
- 关于Java基础的一些笔试题总结
针对近期腾讯.京东.网易等公司的笔试,遇到一些有关Java基础的问题,在此总结,希望能通过这几道经典问题题发散,举一反三,借此打牢基础!自己总结,望提出宝贵意见! 一.关于null的一道小题 先开开 ...
- 有关Java基础的一些笔试题总结
针对近期腾讯.京东.网易等公司的笔试.遇到一些有关Java基础的问题,在此总结.希望能通过这几道经典问题题发散,举一反三.借此打牢基础! 自己总结,望提出宝贵意见! 一.关于null的一道小题 先开开 ...
- python 饥饿的小易(网易笔试题)
本周早些时候,学弟给我发了一道网易的笔试题,饥饿的小易,感觉有点意思-分享给大家 题目描述: 小易总是感觉饥饿,所以作为章鱼的小易经常出去寻找贝壳吃.最开始小易在一个初始位置x_0.对于小易所处的当前 ...
随机推荐
- JQ中的方法、事件及动画
css( ) 除了可以为元素添加样式外,还可用来查询元素,某样式值alert($('.cls1').css('width')); //100px(返回带单位的值)注意:原生CSS样式中有-的去掉并且将 ...
- iOS 开源项目
在 Github 上 Star 太多了,有时候很难找到自己想要的开源库,所以在此记录下来.便于自己开发使用,也顺便分享给大家. 动画 awesome-ios-animation收集了iOS平台下比较主 ...
- iOS多线程简介
1.进程 什么是进程 进程是指在系统中正在运行的一个应用程序 每个进程之间是独立的,每个进程均运行在其专用且受保护的内存空间内 比如同时打开迅雷.Xcode,系统就会分别启动2个进程 2.线程 什么是 ...
- EF DI & MVC
The Repository Pattern with EF Code First & Dependency Injection in ASP.NET MVC3 Ray_Liang, 5 Ju ...
- Android的Message Pool是什么——源码角度分析
原文地址: http://blog.csdn.net/xplee0576/article/details/46875555 Android中,我们在线程之间通信传递通常采用Android的消息机制,而 ...
- android中的线程池学习笔记
阅读书籍: Android开发艺术探索 Android开发进阶从小工到专家 对线程池原理的简单理解: 创建多个线程并且进行管理,提交的任务会被线程池指派给其中的线程进行执行,通过线程池的统一调度和管理 ...
- vim添加代码折叠功能
用空格或者za命名改变,添加如下到vimrc文件 " Enable folding set foldmethod=indent set foldlevel=99 " Enable ...
- TCP三次握手建立连接
基本过程: ISN(初始序号)随时间变化,每一个连接具有不同的ISN,防止在网络延迟中分组被重新发送. 请求端发送SYN(同步序号 )=1,seq=ISN(32bits序号,每4ms+ ...
- Tomcat 启动报错:No default web.xml
原因是:tomcat 中conf 目录中的 web.xml 被无意删除掉了.从其他tomcat中复制一个过来就行了. conf 目录 没有 web.xml 导致的问题是,server.xml 中配置的 ...
- AD 域账号登录
域服务数据读写,有俩种模式 1.轻量级的数据读取 _domain是服务器的域名 获取连接PrincipalContext pc = new PrincipalContext(ContextType.D ...