JavaScript浅析 -- new构造对象

一、构造对象的几种方式

1.字面量法:
var person1 = {
    name: 'peter',
    age: 18,
    sex: 'boy',
    getAge: function() {
        return this.age;
    }
}
var person2 = {
    name: 'john',
    age: 22,
    sex: 'boy',
    getAge: function() {
        return this.age;
    }
}

字面量法就是简单的key:value直接创建,但是有以下两个缺点:

  • 构造麻烦。每次操作都要给所有的变量赋值,都是重复操作的复制粘贴代码很多。
  • 每个使用者都需要了解详细的内部细节,即使只是想个性化改变下name。
2. 函数自动化法:
function createPerson(name, age) {
    return {
        name: name,
        age: age,
        getAge: function() {
            return this.age;
        }
    }
}
var person1 = createPerson('peter', 18);
  • 优点:使用此法简化了构造的过程,每次构造只要调用函数并传入对应的参数即可。也不需要知道内部实现的逻辑。
  • 缺点:函数返回的都是一个Object类型的对象,辨识度不高。
3. 构造函数法:
function Person(name, age) {
    this.name = name;
    this.age = age;
    this.getAge = function() {
        return this.age;
    }
}
var person1 = new Person('peter', 18);

function Car(speed) {
    this.speed = speed;
}
var car1 = new Car(50);

用这种方法构造出来的对象类型可以自由定义,比如上面的person1的类型对象是Person,car1是Car,很好区分。如果用第二种的话则他们的类型都是Object。

二、new的过程发生了啥

也许有些小伙伴会有疑惑,为啥会有个new,而不是直接执行方法,这个new到底做了些啥?其实,在new的过程中,主要做了这三件事:

  1. 创建一个空的对象,并将该对象的proto指向了Person.prototype
  2. 执行函数,函数里面对this操作相当于对这个新建的空的对象操作。
  3. 函数执行完毕之后,返回这个空的对象。
JavaScript浅析 -- new构造对象_第1张图片
原型图

如上图,是构造函数法代码的简单原型图。每个对象都有一个_proto_,每个方法都有一个prototype,而new的最重要一步就是将生成空对象的_proto_指向了Person的prototype。

三、new一些补充

  1. new本身就能执行构造函数,所以后面加不加括号都无所谓,但是为了表示是个函数,推荐加上括号。
  2. 若构造函数前不加new,则相当于普通的执行方法,就不再执行上面说的new的过程,会导致其中的this不再指向实例对象,所以记得加new。若普通函数(内部没有this)加new,则返回一个空对象。
  3. 在构造函数里,可以通过new.target获得当前的构造函数,若返回undefined则证明当前没有使用new操作。另一种方法是判断this instanceof 构造函数,看是否返回true来判断是否使用new,若为false则返回new 构造函数()
function f() {
  if (!new.target) {
    throw new Error('请使用 new 命令调用!');
  }
}
f(); // Uncaught Error: 请使用 new 命令调用!
  1. 构造函数的最后不需要return。若加了return且返回了一个对象,则会用该对象替换当前创建的实例对象。若返回基本数据类型则忽略返回原来实例对象。
var Human = function (){
  this.age = 18;
  return { age: 20 };
};
(new Human()).age; // 20

var Human = function () {
  this.age = 18;
  return 66;
};
(new Human()) === 66; // false

你可能感兴趣的:(JavaScript浅析 -- new构造对象)