1

步骤

  1. 用new Object() 的方式新建了一个对象 obj(创建一个新的对象)
  2. 取出第一个参数,就是我们要传入的构造函数。此外因为 shift 会修改原数组,所以 arguments 会被去除第一个参数
  3. 将 obj 的原型指向构造函数,这样 obj 就可以访问到构造函数原型中的属性(把obj的__proto__指向fn的prototype,实现继承)
  4. 使用 apply,改变构造函数 this 的指向到新建的对象,这样 obj 就可以访问到构造函数中的属性(改变this的指向,执行构造函数、传递参数,fn.apply(obj,) 或者 fn.call())
  5. 返回 obj(返回新的对象obj)

    other

  6. shift() 方法用于把数组的第一个元素从其中删除,并返回第一个元素的值
  7. 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;
    
    };

注意写错的地方

clipboard.png


渣渣辉
1.3k 声望147 粉丝