前言
本文1021字,阅读大约须要5分钟。前端
总括: 本文对new进行了一个简单介绍,而后使用一个函数模拟实现了new操做符作的事情。app
- 参考文档:new 运算符
- 公众号:「前端进阶学习」,回复「666」,获取一揽子前端技术书籍
人生是没有毕业的学校。函数
正文
new
是JS中的一个关键字,用来将构造函数实例化的一个运算符。例子:学习
function Animal(name) { this.name = name; } Animal.prototype.sayName = function() { console.log("I'm " + this.name); } var cat = new Animal('Tom'); console.log(cat.name); // Tom console.log(cat.__proto__ === Animal.prototype); // true cat.sayName(); // I'm Tom
从上面的例子能够得出两点结论:测试
new
操做符实例化了一个对象;- 这个对象能够访问构造函数的属性;
- 这个对象能够访问构造函数原型上的属性;
- 对象的**_proto_**属性指向了构造函数的原型;
因为new
是关键字,咱们只能去声明一个函数去实现new
的功能,首先实现上面的三个特性,初版代码以下:this
附:对原型原型链不熟悉的能够先看理解Javascript的原型和原型链。prototype
// construct: 构造函数 function newFunction() { var res = {}; // 排除第一个构造函数参数 var construct = Array.prototype.shift.call(arguments); res.__proto__ = construct.prototype; // 使用apply执行构造函数,将构造函数的属性挂载在res上面 construct.apply(res, arguments); return res; }
咱们测试下:code
function newFunction() { var res = {}; var construct = Array.prototype.shift.call(arguments); res.__proto__ = construct.prototype; construct.apply(res, arguments); return res; } function Animal(name) { this.name = name; } Animal.prototype.sayName = function() { console.log("I'm " + this.name); } var cat = newFunction(Animal, 'Tom'); console.log(cat.name); // Tom console.log(cat.__proto__ === Animal.prototype); // true cat.sayName(); // I'm Tom
一切正常。new
的特性实现已经80%,但new
还有一个特性:对象
function Animal(name) { this.name = name; return { prop: 'test' }; } var cat = new Animal('Tom'); console.log(cat.prop); // test console.log(cat.name); // undefined console.log(cat.__proto__ === Object.prototype); // true console.log(cat.__proto__ === Animal.prototype); // false
如上,若是构造函数return
了一个对象,那么new
操做后返回的是构造函数return
的对象。让咱们来实现下这个特性,最终版代码以下:blog
// construct: 构造函数 function newFunction() { var res = {}; // 排除第一个构造函数参数 var construct = Array.prototype.shift.call(arguments); res.__proto__ = construct.prototype; // 使用apply执行构造函数,将构造函数的属性挂载在res上面 var conRes = construct.apply(res, arguments); // 判断返回类型 return conRes instanceof Object ? conRes : res; }
测试下:
function Animal(name) { this.name = name; return { prop: 'test' }; } var cat = newFunction(Animal, 'Tom'); console.log(cat.prop); // test console.log(cat.name); // undefined console.log(cat.__proto__ === Object.prototype); // true console.log(cat.__proto__ === Animal.prototype); // false
以上代码就是咱们最终对new
操做符的模拟实现。咱们再来看下官方对new
的解释
引用MDN对new
运算符的定义:
new
运算符建立一个用户定义的对象类型的实例或具备构造函数的内置对象的实例。
new
操做符会干下面这些事:
- 建立一个空的简单JavaScript对象(即
{}
); - 连接该对象(即设置该对象的构造函数)到另外一个对象 ;
- 将步骤1新建立的对象做为
this
的上下文 ; - 若是该函数没有返回对象,则返回
this
。
4条都已经实现。还有一个更好的实现,就是经过Object.create
去建立一个空的对象:
// construct: 构造函数 function newFunction() { // 经过Object.create建立一个空对象; var res = Object.create(null); // 排除第一个构造函数参数 var construct = Array.prototype.shift.call(arguments); res.__proto__ = construct.prototype; // 使用apply执行构造函数,将构造函数的属性挂载在res上面 var conRes = construct.apply(res, arguments); // 判断返回类型 return conRes instanceof Object ? conRes : res; }
以上。
能力有限,水平通常,欢迎勘误,不胜感激。
订阅更多文章可关注公众号「前端进阶学习」,回复「666」,获取一揽子前端技术书籍