步骤
- 用new Object() 的方式新建了一个对象 obj(创建一个新的对象)
- 取出第一个参数,就是我们要传入的构造函数。此外因为 shift 会修改原数组,所以 arguments 会被去除第一个参数
- 将 obj 的原型指向构造函数,这样 obj 就可以访问到构造函数原型中的属性(把obj的__proto__指向fn的prototype,实现继承)
- 使用 apply,改变构造函数 this 的指向到新建的对象,这样 obj 就可以访问到构造函数中的属性(改变this的指向,执行构造函数、传递参数,fn.apply(obj,) 或者 fn.call())
返回 obj(返回新的对象obj)
other
- shift() 方法用于把数组的第一个元素从其中删除,并返回第一个元素的值
arguments是一个类数组对象,虽然他也有下标,但并非真正的数组,所以他不能和数组一样进行排序添加之类的操作,这种情况下 借用array.prototype对象上的方法,可以对arguments完成push,shift等操作,array.prototypr.slice()就可以吧arguments转换成真正的数组
function argstoArr() { // return Array.prototype.shift.call(arguments) return [].shift.call(arguments) } var arr1 = argstoArr(1, 2, 3) console.log(arr1) //1
代码
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> </head> <body> <script> function Person(name, age) { this.name = name; this.age = age; this.say = function() { alert(this.name) } } Person.prototype.sex = '男' var p1 = new Person('jie', 12) p1.say() function create() { let obj = new Object(); let Con = [].shift.call(arguments) obj.__proto__ = Con.prototype; let ret = Con.apply(obj, arguments) return ret instanceof Object ? ret : obj } var p2 = create(Person, 'biao', 22) p2.say() </script> </body> </html>
在这个例子中,构造函数返回了一个对象,在实例 person 中只能访问返回的对象中的属性。
而且还要注意一点,在这里我们是返回了一个对象,假如我们只是返回一个基本类型的值呢?
再举个例子:function Otaku (name, age) { this.strength = 60; this.age = age; return 'handsome boy'; } var person = new Otaku('Kevin', '18'); console.log(person.name) // undefined console.log(person.habit) // undefined console.log(person.strength) // 60 console.log(person.age) // 18复制代码结果完全颠倒过来,这次尽管有返回值,但是相当于没有返回值进行处理。
所以我们还需要判断返回的值是不是一个对象,如果是一个对象,我们就返回这个对象,如果没有,我们该返回什么就返回什么。
再来看第二版的代码,也是最后一版的代码:
// 第二版的代码function objectFactory() { var obj = new Object(), Constructor = [].shift.call(arguments); obj.__proto__ = Constructor.prototype; var ret = Constructor.apply(obj, arguments); return typeof ret === 'object' ? ret : obj; };
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。