js面试-手写代码实现new操作符的功能
我们要搞清楚new操作符到底做了一些什么事情?
1.创建一个新的对象
2.将构造函数的作用域赋给新对象(因此this指向了这个新对象)
3.执行构造函数中的代码(为这个新对象添加属性)
4.返回新对象
上面给出了new操作符到底做了一些什么事情,我们就一步一步的实现这些,是不是就实现了new操作符的功能。
首先定义一个构造函数Person如下:
function Person(name) {
this.name = name;
}
Person.prototype.sayName = function () {
console.log(this.name);
}
然后创建模拟new操作符功能的函数如下:
function Person(name) {
this.name = name;
}
Person.prototype.sayName = function () {
console.log(this.name);
}
function createPerson() {
// 1 创建一个新的对象
var o = {};
// 2 获取构造函数,以便实现作用域的绑定
var _constructor = [].shift.call(arguments);
// 3 由于通过new操作创建的对象实例内部的不可访问的属性[[Prototype]](有些浏览器里面为__proto__)
//指向的是构造函数的原型对象的,所以这里实现手动绑定。
o.__proto__ = _constructor.prototype;
// 4.作用域的绑定使用apply改变this的指向
_constructor.apply(o, arguments);
return o;
}
var person1 = createPerson(Person, 'ydb');
person1.sayName();
这样子就实现了new操作符的功能了。
其实上面代码还可以这样子写:
function Person(name) {
this.name = name;
}
Person.prototype.sayName = function () {
console.log(this.name);
}
function createPerson() {
// 1 获取构造函数,以便实现作用域的绑定
var _constructor = [].shift.call(arguments);
// 2 创建一个对象
var o = Object.create(_constructor.prototype);
// 由于通过new操作创建的对象实例内部的不可访问的属性[[Prototype]](有些浏览器里面为__proto__)
//指向的是构造函数的原型对象的。
//而Object.create()方法创建一个新对象,使用现有的对象来提供新创建的对象的__proto__。// 4.作用域的绑定
_constructor.apply(o, arguments);
return o;
}
var person1 = createPerson(Person, 'ydb');
person1.sayName();
用Object.create可以创建一个没有任何属性的对象,如下:
var o = Object.create(null);
js面试-手写代码实现new操作符的功能的更多相关文章
- 2019前端面试系列——JS高频手写代码题
实现 new 方法 /* * 1.创建一个空对象 * 2.链接到原型 * 3.绑定this值 * 4.返回新对象 */ // 第一种实现 function createNew() { let obj ...
- 前端面试手写代码——JS函数柯里化
目录 1 什么是函数柯里化 2 柯里化的作用和特点 2.1 参数复用 2.2 提前返回 2.3 延迟执行 3 封装通用柯里化工具函数 4 总结和补充 1 什么是函数柯里化 在计算机科学中,柯里化(Cu ...
- 前端面试手写代码——call、apply、bind
1 call.apply.bind 用法及对比 1.1 Function.prototype 三者都是Function原型上的方法,所有函数都能调用它们 Function.prototype.call ...
- 前端面试手写代码——模拟实现new运算符
目录 1 new 运算符简介 2 new 究竟干了什么事 3 模拟实现 new 运算符 4 补充 预备知识: 了解原型和原型链 了解this绑定 1 new 运算符简介 MDN文档:new 运算符创建 ...
- 前端面试手写代码——JS数组去重
目录 1 测试用例 2 JS 数组去重4大类型 2.1 元素比较型 2.1.1 双层 for 循环逐一比较(es5常用) 2.1.2 排序相邻比较 2.2 查找元素位置型 2.2.1 indexOf ...
- Java面试手写代码题
1.栈实现 2.Iterator实现 3.单例 4.多线和控制(暂停,恢复,停止) 5.生产者消费者
- .netER的未来路,关于基础是否重要和应该自己手写代码吗?
http://www.cnblogs.com/onepiece_wang/p/5558341.html#!comments 引用"基础知识的学习,一开始可能是背书,但是在后续若干年的工作过程 ...
- UI到底应该用xib/storyboard完成,还是用手写代码来完成?
UI到底应该用xib/storyboard完成,还是用手写代码来完成? 文章来源:http://blog.csdn.net/libaineu2004/article/details/45488665 ...
- javaScript(js)手写原生任务定时器源码
javaScript(js)手写原生任务定时器 功能介绍 定时器顾名思义就是在某个特定的时间去执行一些任务,现代的应用程序早已不是以前的那些由简单的增删改查拼凑而成的程序了,高复杂性早已是标配,而任务 ...
随机推荐
- Log4J基础
Log4j由三个重要的组件构成:日志信息的优先级,日志信息的输出目的地,日志信息的输出格式.日志信息的优先级从高到低有ERROR.WARN. INFO.DEBUG,分别用来指定这条日志信息的重要程度: ...
- 108)PHP分页显示
一个代码页的链接:https://www.cnblogs.com/mmykdbc/p/6688460.html 首先一个简单的代码展示: 目录关系: 数据库表格展示: 结果展示: 然后 代码展示 ...
- 2)thinkphp的带有命名空间的自动加载机制
(1)为啥thinkphp里面的文件要是写你的命名空间,要与你的路径一样,因为在thinkphp实现自动加载机制的原理,就是靠的你的命名空间对应这个路径,然后自动加载机制通过这个路径找到你的类文件,然 ...
- java作业-----方法重载
满足方法重载的条件:1.方法名相同 2.参数类型不同,参数个数不同,参数类型的顺序不同. 同时,方法的返回值不作为方法重载的判断条件.
- [LC] 13. Roman to Integer
Roman numerals are represented by seven different symbols: I, V, X, L, C, Dand M. Symbol Value I 1 V ...
- 四、RabbitMQ Exchange类型
RabbitMQ整体上是一个生产者与消费者模型,主要负责接收.存储和转发消息.可以把消息传递的过程想象成:当你将一个包裹送到邮局,邮局会暂存并最终将邮件通过邮递员送到收件人的手上,RabbitMQ就好 ...
- python函数参数理解
1.位置参数 函数调用时,参数赋值按照位置顺序依次赋值. e.g. def function(x): 3 return x * x 5 print function(2) 输出结果: 4 def fu ...
- android优化中国风应用、完整NBA客户端、动态积分效果、文件传输、小说阅读器等源码
Android精选源码 android拖拽下拉关闭效果源码 一款优雅的中国风Android App源码 EasySignSeekBar一个漂亮而强大的自定义view15 android仿蘑菇街,蜜芽宝 ...
- [LC] 225. Implement Stack using Queues
Implement the following operations of a stack using queues. push(x) -- Push element x onto stack. po ...
- [LC] 243. Shortest Word Distance
Given a list of words and two words word1 and word2, return the shortest distance between these two ...