new运算符 能根据需求来创建对象的实例 通过与构造函数和一系列初始化过程中使用的可选参数来创建对象的实例,对象创建完成后,新创建的对象继承自构造函数的原型
function Person(name) { this.name = name; } Person.prototype.say = function() { return this.name; } var person = new Person("haha"); console.log(person.say()); //haha
上面是我们比较常用的使用new + 构造函数的场景 让我们看看new 在这里面都做了什么
(1)创建了一个对象字面量{}
(2)将新创建的对象的构造函数链接到函数person上 也就是绑定this 通过查看person.constructor就能看出来 执行构造函数 这样就将构造函数上创建的属性和方法添加到新创建的对象上了
(3)将新创建对象的原型链接到构造函数的prototype上
(4)根据传入的参数,对对象的属性进行赋值 返回创建的对象 this
也就是我们可以这样的理解上面这个过程
var person = {}; //创建一个空的对象 person.__proto__ = Person.prototype; //继承构造函数的原型 person.name = "haha"; //根据传入的参数实例化属性 console.log(person.say()); //'haha'
上面模拟new + 构造函数的模式
有几个需要注意的问题
当我们继承了构造函数的原型对象的时候 你仍然可以通过在构造函数的原型对象上添加属性和方法
function Person(name) { this.name = name; } Person.prototype.say = function() { return this.name; } var person = new Person("haha"); console.log(person.say());//haha Person.prototype.test = 1; console.log(person.test);//1
注意这里是一种浅拷贝 当我们修改试图修改构造函数原型上的属性的时候,其实是在相应的对象上新创建了一个属性,覆盖了原型对象上的属性,并且当我们删除自身的属性的时候,仍然访问到构造函数原型的属性
var person1 = new Person("1"); var person2 = new Person("2"); Person.prototype.test = [1,2]; //在构造函数的原型对象上添加属性 console.log(person1.test); //[1,2] person1.test = [1,2,3]; console.log(person1.test);//[1,2,3] 访问的是对象自身的test属性 console.log(person1.__proto__.test); // [1,2] 访问够构造函数原型的test属性 console.log(person2.test); //[1,2] 构造函数原型的test属性 delete person1.test; console.log(person1.test); // [1,2] 删除自身test的属性 就恢复了对构造函数原型对象的属性的访问 (原型链的查找)
如果我们在这样使用一个构造函数呢 var person = Person()
这是执行构造函数的this执行的就不是我们新创建的构造函数了 而是window 创建的属性也是在windwo上 具体的解释请看我的另一篇文章
http://www.cnblogs.com/tiantianwaigong/p/4543428.html 面试遇到的问题的第四题
最近又看了园内博友的一篇文章 http://www.cnblogs.com/xxcanghai/p/5189353.html 里面涉及都new的优先级的问题 大家可以去好好了解下