- UID
- 656607
- 在线时间
- 小时
- 积分
- 632
- 帖子
- 离线
- 18644 天
- 注册时间
- 2013-9-17
|
JavaScript中new操作符是如何实例化一个对象的
new操作符进行了什么动作? //一个面试题
在js中,每一个函数都有一个原型 - prototype,原型的存在使得原型链存在,也就使得继承成为了可能
但是,函数的原型并不是一个函数,而是一个对象(此处的对象不包含function)
那么,对象的原型是什么?
对象是没有原型的,但是,每一个对象有一个跟原型概念和作用都类似的内部属性,__proto__(前后两下划线,此对象只在chorme和fireFox等浏览器中可见);对象的__proto__属性指向创建此对象的构造函数的原型,如:
function A(){}
var a = new A;
a.__proto__===A.prototype //true
然后,A.prototype也是一个对象,所以也拥有__proto__属性;
因为A.prototype对象是A对象(function也是对象)的属性,所以,A.prototype.__proto__===A的构造函数.prototype;
那么,A的构造函数是什么呢?
很明显,是Object;所以,A.prototype.__proto===Object.prototype; //true
所以,原型链就是这么一级一级上去的.
这些跟new操作符有什么关系呢?
new操作符就是创建了构造函数的一个实例(也是对象);
如:
var a = new A;
alert(typeof a); //object;
所以,a有__proto__属性,指向谁?A的原型,A.prototype;
那么,此处我们就能理解为什么a对象拥有A原型上的属性和方法了.
那么,new 还做了什么,使得a还拥有构造函数定义直接定义的方法和属性?
apply();函数
A.apply(a,arguments);
这样,a就拥有了A构造函数定义的属性和方法.
所以,我们得出结论
new操作符,把对象的__proto__属性指向构造函数的原型,然后,利用apply函数运行了一次构造函数,使对象拥有了构造函数和构造函数原型链上的所有属性和方法.
为了验证正确性,我们来做一个实例:
不用new 操作符来创建一个构造函数的实例对象(就是达到跟new一样的效果):
function A(age){
this.age=age;
}
A.prototype.setAge=function(age){
this.age=age;
}
var a1 = new A(10); //new操作符,作为对比
A.newRealize=function(){ //模拟new操作的函数
var o ={}; //创建临时对象
o.__proto__=A.prototype;
A.apply(o,arguments);
return o;
}
var a2 = A.newRealize(10);
alert(a1 instanceof A); //true
alert(a2 instanceof A); //true
alert(a2.age); //10
a2.setAge(20);
alert(a2.age); //20
提示:您可以先修改部分代码再运行
|
|