一. new是干嘛的?
new操作符用来生成一个新的对象, 它后面必须跟上一个函数(否则, 会抛出TypeError异常), 这个
函数就是我们常说的构造函数.
二. new操作构造函数生成实例的过程
(1) 首先, 当我们使用new操作符时, js会先创建一个空的对象;
(2) 然后, 构造函数中的this指向该空对象;
(3) 其次, 在构造函数中通过操作this, 来给这个空对象赋予相应的属性;
(4) 最后, 返回这个经过处理的"空对象"(此时, 对象已经不是空的了).
三. new操作构造函数的注意事项
(1) 如果构造函数的返回值是一个原始类型(非引用对象, 如字符串), 那么返回值为new创建的"空对象", 如:
var obj = new function() { return "code";};
alert(obj); // [object object]
(2) 如果构造函数的返回值是一个引用对象(数组, 对象, 函数等), 那么返回值会覆盖new创建的"空对象", 如:
var obj = new function() { return new String("code"); };
alert(obj); // "code"
四.原理
|
这样代码的结果是什么,我们在Javascript引擎中看到的对象模型是:
new操作符具体干了什么呢?其实很简单,就干了三件事情。
|
|
第一行,我们创建了一个空对象obj
第二行,我们将这个空对象的__proto__成员指向了Base函数对象prototype成员对象
第三行,我们将Base函数对象的this指针替换成obj,然后再调用Base函数,于是我们就给obj对象赋值了一个id成员变量,这个成员变量的值是”base”,关于call函数的用法,请参看陈皓《Javascript 面向对象编程》文章
如果我们给Base.prototype的对象添加一些函数会有什么效果呢?
例如代码如下:
|
|
那么当我们使用new创建一个新对象的时候,根据__proto__的特性,toString这个方法也可以做新对象的方法被访问到。于是我们看到了:
构造子中,我们来设置‘类’的成员变量(例如:例子中的id),构造子对象prototype中我们来设置‘类’的公共方法。于是通过函数对象和Javascript特有的__proto__与prototype成员及new操作符,模拟出类和类实例化的效果。
五。代码示例
- <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
- <html>
- <head>
- <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
- <title>Insert title here</title>
- </head>
- <body>
- <script type="text/javascript">
- /*没有返回值
- function Test1(str) {
- this.a = str;
- }
- //new
- var myTest1 = new Test1('myTest1');
- alert(myTest1);//object Object
- //no new
- var myTest1 = Test1('myTest1');
- alert(myTest1);//undefined
- */
- /*有返回值
- function Test2(str) {
- this.a = str;
- return this.a;
- }
- //new
- var myTest2 = new Test2('myTest2');
- alert(myTest2);//object Object myTest2.a就是myTest2
- //no new
- var myTest2 = Test2('myTest2');
- alert(myTest2);//myTest2
- */
- /*返回值为new对象
- function Test3(str) {
- this.a = str;
- return new String(this.a);
- }
- var myTest3 = new Test3('myTest3');
- alert(myTest3);//String myTest3
- */
- /* new this
- function Test4(str) {
- this.a = str;
- }
- //对象的get_string方法
- Test4.prototype.get_string = function() {
- return this.a;//this指这个新对象 this.a 新对象的a属性值
- }
- var myTest4 = new Test4('myTest4');
- alert(myTest4.get_string());//myTest4
- */
- /*js 伪继承 伪类
- function Test5(str) {
- this.a = str;
- }
- Test5.prototype.get_Test5String = function() {
- return this.a;
- }
- var myTest5 = new Test5('myTest5');
- //alert(myTest5.get_Test5String());
- function Test6(str) {
- this.b = str;
- }
- Test6.prototype = new Test5('myTest5');//必须放在get_Test6String方法前 不然就冲掉了
- Test6.prototype.get_Test6String = function() {
- return this.b;
- }
- var myTest6 = new Test6('myTest6');
- alert(myTest6.get_Test6String());//myTest6
- alert(myTest6.get_Test5String());//myTest5
- */
- </script>
- </body>
- </html>
原帖: