代码
// 实现一个new操作符
function myNew() {
// 创建一个新对象obj
let obj = new Object();
// 取参数的第一项为构造函数fn,这里可以写(arguments,1)也可以直接(arguments),都是代表参数的第一项,取构造函数
let fn = [].shift.call(arguments);
// 将obj.__proto__连接到构造函数fn的原型
obj.__proto__ = fn.prototype;
// result接收构造函数执行后的返回结果
let result = fn.apply(obj, arguments);
// 如果构造函数返回一个对象,则将该对象返回,否则返回步骤1创建的对象
return typeof result === 'object' ? result : obj;
}
//测试
function Person(name) {
this.name = name;
}
var p2 = myNew(Person, "小明");
console.log(p2.name);
解释:
- let fn = [].shift.call(arguments);
[] 可以替换为 Array.prototype
shift:方法原理就是根据传入的参数(值)对原数组(或者类数组)进行遍历获取,赋给新数组然后返回。如果没有参数便复制整个原数组(或者类数组),后赋给新数组然后返回。
call:第一个参数都是一个对象或者 ‘this’ 注意this加引号了, apply第二个参数接收一个数组,call则不是,call可以有n个参数有多少放多少就行
重点
slice内部实现是使用的this代表调用对象,那么当[].slice.call() 传入 arguments对象的时候,通过 call函数改变原来 slice方法的this指向, 使其指向arguments,并对arguments进行复制操作,而后返回一个新数组。至此便是完成了arguments类数组转为数组的目的!