new 关键字
实现步骤
实现 new
之前,我们需要理解 new
实例化构造函数时做了哪些事情(以下是 JS
高级程序设计中的说法):
- 创建一个新对象;
- 将构造函数的作用域赋给新对象(因此
this
就指向了这个新对象); - 执行构造函数中的代码(为这个新对象添加属性);
- 返回新对象
实现代码
使用示例
我们先看如何使用这个将被实现的 _new
方法:
JS
// Person 构造函数
function Person(name, age) {
this.name = name;
this.age = age;
}
// 第一个参数是构造函数,后面是参数列表
// 所以 _new 函数需要取出 arguments 第一个参数,它就是构造函数
let person = _new(Person, 'zhang', 18);
// Person 构造函数
function Person(name, age) {
this.name = name;
this.age = age;
}
// 第一个参数是构造函数,后面是参数列表
// 所以 _new 函数需要取出 arguments 第一个参数,它就是构造函数
let person = _new(Person, 'zhang', 18);
ES5 实现
JS
// ES5 写法,因为不知道参数有多少个,所以只能通过内部的 arguments 参数类数组进行获取
function _new() {
// 1 创建一个新对象
var obj = new Object();
// 2. 将构造函数的作用域赋给新对象
// 2.1 我们需要先获取到构造函数
var Fn = [].shift.call(arguments);
// 2.2 将构造函数的作用域赋给新对象
obj.__ptoto__ = Fn.prototype;
// 3. 执行构造函数中的代码 注意:此时arguments已经在上一步中被转为数组,且去掉了第一个参数
var result = Fn.apply(obj, arguments);
// 4. 返回新对象 注意:需要判断返回 null 与 function 情况
return result instanceof Object ? result : obj;
}
// ES5 写法,因为不知道参数有多少个,所以只能通过内部的 arguments 参数类数组进行获取
function _new() {
// 1 创建一个新对象
var obj = new Object();
// 2. 将构造函数的作用域赋给新对象
// 2.1 我们需要先获取到构造函数
var Fn = [].shift.call(arguments);
// 2.2 将构造函数的作用域赋给新对象
obj.__ptoto__ = Fn.prototype;
// 3. 执行构造函数中的代码 注意:此时arguments已经在上一步中被转为数组,且去掉了第一个参数
var result = Fn.apply(obj, arguments);
// 4. 返回新对象 注意:需要判断返回 null 与 function 情况
return result instanceof Object ? result : obj;
}
ES6 实现
JS
// ES6 写法,因为 ES6 增加了 rest 参数,这样可以很方便的接受其它参数
function _new(fn, ...args) {
// 整合了1、2步
const obj = Object.create(fn.prototype);
const result = fn.apply(obj, args);
// 如果函数返回 非空并是对象 返回 value 否则 返回 obj
return result instanceof Object ? result : obj;
}
// ES6 写法,因为 ES6 增加了 rest 参数,这样可以很方便的接受其它参数
function _new(fn, ...args) {
// 整合了1、2步
const obj = Object.create(fn.prototype);
const result = fn.apply(obj, args);
// 如果函数返回 非空并是对象 返回 value 否则 返回 obj
return result instanceof Object ? result : obj;
}