JavaScript之new

原文出至冴羽的博客


JavaScript之new

  1. new是什么

    new运算符创建一个用户自定义的对象类型的实例或具有构造函数的内置对象类型之一

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    function Otaku(name, age) {
    this.name = name;
    this.age = age;

    this.habit = 'games';
    }
    Otaku.prototype.strength = 1;
    Otaku.prototype.sayYourname = function(){
    console.log('i am ' + this.name);
    }

    var person = new Otaku('blue', 18)
    console.log(person.name ) // blue
    console.log(person.age) // 18
    console.log(person.habit) // games
    person.sayYourname() // i am blue

    从这里可以看出person这个实例对象能够

    • 访问到Otaku构造函数中的属性
    • 访问到Otaku.prototype的属性
      写一个函数,命名为objectFactory来模拟new的效果
      1
      2
      3
      4
      5
      6
      7
      8
      function Otaku () {
      ……
      }

      // 使用 new
      var person = new Otaku(……);
      // 使用 objectFactory
      var person = objectFactory(Otaku,
  2. 初步实现

    这里的思想就是把传递进来的参数都挂到一个对象上去,并且让这个对象的proto属性指向传入函数的prototype,然后返回这个对象

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    function objectFactory() {
    var obj = new Object();
    Constructor = [].shift.call(arguments);
    obj.__proto__ = Constructor.prototype;
    Constructor.apply(obj, arguments)
    return obj;
    }

    var person1 = objectFactory(Otaku,'blue',18)
    console.log(person1)
    person1.sayYourname()
    1. 用new Object() 的方式新建了一个对象 obj
    2. 取出第一个参数,就是我们要传入的构造函数。此外因为 shift 会修改原数组,所以 arguments 会被去除第一个参数
    3. 将obj的原型指向构造函数,这样obj就可以访问到构造函数原型中的属性
    4. 使用apply改变构造函数this的指向到新建的对象,这样obj就可以访问到构造函数中的属性
    5. 返回obj
  3. 返回值效果实现

    1. 当构造函数返回了一个对象,实例person只能访问到返回的对象中的属性
    2. 当构造函数返回一个基本类型值,相当于没有返回值
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      30
      31
      32
       function Otaku (name, age) {
      this.strength = 60;
      this.age = age;

      return {
      name: name,
      habit: 'Games'
      }
      }

      var person = new Otaku('Kevin', '18');

      console.log(person.name) // Kevin
      console.log(person.habit) // Games
      console.log(person.strength) // undefined
      console.log(person.age) // undefined

      // ------------------------//

      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
  4. 结合上面两种情况我们需要添加一个判断,如果返回值是一个对象,就返回这个对象,如果没有,该返回什么就返回什么。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    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;

    };