一道有意思的笔试题引发的对于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.对于小易所处的当前 ...
随机推荐
- 中文字体font-family常用列表
Windows的一些: 黑体:SimHei 宋体:SimSun 新宋体:NSimSun 仿宋:FangSong 楷体:KaiTi 仿宋_GB2312:FangSong_GB2312 楷体_GB2312 ...
- 三道Javascript的练习题
有语句“var x=0;while(____) x+=2;”,要使while循环体执行10次,空白处的循环判定式应写为: A.x<10B. x<=10C.x<20D.x<=20 ...
- PHP语法
* PHP语法 * 常量与变量 * 常量 - 一旦定义并初始化后,值不会改变 * 使用const关键字 const 常量名=常量值 * define(常量名,常量值) * 变量 - "$&q ...
- Android开发—已root的手机获取data路径
开发android的时候,尽管手机已经root但是DDMS中还是没有data/data路径怎么办? 可以用cmd命令提示符为逐个文件夹设置权限: 打开cmd,输入 adb shell 回车—> ...
- Material Design 概念,环境和基本属性
Material Design 概念,环境和基本属性 Material Design是随Android 5.0推出的一种设计概念, 涉及到了跨平台和设备的视觉,动态,交互设计等方面. 设计概念 M ...
- JavaScript单元测试框架JsUnit基本介绍和使用
JavaScript单元测试框架JsUnit基本介绍和使用 XUnit framework XUnit是一套标准化的独立于语言的概念和结构集合,用于编写和运行单元测试(Unit tests). 每一个 ...
- 每个程序员都会的 35 个 jQuery 小技巧
1. 禁止右键点击 $(document).ready(function(){ $(document).bind("contextmenu",function(e){ return ...
- IOS开发基础知识--碎片31
1:UITableViewCell drawInRect 在iOS7中失败 解决办法,把Cell里的布局移到新建的View里面,在View里面实现DrawInRect,然后在Cell里面加载View, ...
- databtables 设置(显示)行号
var table = $('#priceStrategtyTable').DataTable({ "rowCallback": function( row, da ...
- [Java编程思想-学习笔记]第1章 对象导论
1.1 抽象过程 Java是一门面向对象的语言,它的一个优点在于只针对待解问题抽象,而不用为具体的计算机结构而烦心,这使得Java有完美的移植性,也即Java的口号"Write Once, ...