深入理解javascript new的机制

jopen 9年前

我们在使用对象的时候,除了一些浏览器内置的单体对象可以直接使用外,都会new一个出来使用。

1.最简单的莫过于如下获取一个Object对象实例

var obj = new Object();

说明:此时的new关键字干了最有用的一件事就是,继承了所有Object.prototype上的方法,这个可以去查看一下es5的参考资料中Object.prototype的方法列表。也就是说此时的obj对象可以使用所有继承而来的方法了!

2.然而是构造函数模式让我们对new有了一个深入的了解!

function Person(name,age){      this.name = name;      this.age = age;      this.sayName = function(){          console.log(this.name);      }  }  var person1 = new Person("wang",23);  var person2 = new Person("jiang",24);  var person3 = new Person;//当不传参数的时候


我们很容易知道构造函数使得每个实例都独自获取了一份属性和方法。但是这是怎么实现出来的呢?

new过程中发生了什么?

1).创建一个对象。

2).将构造函数的作用域赋给新对象(因此this就指向了新对象)

3).执行构造函数中的代码(为新对象添加属性)

4).返回新对象

值得注意的是它们的继承关系是:person1/person2/person3继承于Person,而Person继承于Object(一切对象皆继承于Object)

如果理解了上面的东西,在一些简单编程中遇到new,基本也够了。

下面继续继续介绍一些有关new的话题

3.模块模式(Moudle模式),下面讲解一个最简单的模块模式例子

var Calculator = function (eq) {      //这里可以声明私有成员      var name = 2;      var eqCtl = document.getElementById(eq);        return {          // 暴露公开的成员          name : name,          add: function (x, y) {              var val = x + y;              eqCtl.innerHTML = val;          }      };  };  var c1 = new Calculator('eq');  var c2 = new Calculator('la');  c1.name = 3;//c1的name属性改变了却不会影响c2的name属性  console.log(c1);  console.log(c2);  c1.add(2, 2);


值得注意的是,在Calculator这个构造函数中返回了一个对象!

说明:如果构造函数中返回了一个对象,(第4步)那么new出来的对象将会被返回的对象覆盖。模块模式的结果是c1和c2都从返回的对象copy了一份属性和方法,它们之间互不影响。

继承关系也变了,c1和c2都直接继承于Object