通过例子深入理解javascript中的new操作符

1.首先看一道题目

1 function Cat(name,age){
2      this.name=name;
3      this.age=age;
4 }
5 console.log(new Cat('miaomiao',18));  
6 //Cat {name: "miaomiao", age: 18}

2.那么这里面的this指的是什么呢

1 function Cat(name,age){
2       console.log(this);//Cat {}
3       this.name=name;
4       this.age=age;
5 }
6 new Cat('miaomiao',18);

3.我们发现this是一个名为Cat的空对象,那么后两句(this.name=name;this.age=age)就相当于var Cat={};Cat.name=name;Cat.age=age;是这样的么我们来试一下

1 function Cat(name,age){
2       var Cat = {};
3       Cat.name=name;
4       Cat.age=age;
5 }
6 console.log(new Cat('miaomiao',18));  
7 //Cat {}

4.发现并不是那么回事,这是为什么,在javascript中如果没有return 那么函数就会默认return this为了验证我们在函数最后面return Cat即可

1 function Cat(name,age){
2       var Cat = {};
3       Cat.name=name;
4       Cat.age=age;
5       return Cat;
6 }
7 console.log(new Cat('miaomiao',18));  
8 //Object {name: "miaomiao", age: 18}

5.好像成功了,我们和之前对比一下

1 function Cat(name,age){
2       this.name=name;
3       this.age=age;
4  }
5  console.log(new Cat('miaomiao',18));  
6 //Cat {name: "miaomiao", age: 18}

6.函数的作用我们理解的差不多,下面开始探索NEW,试想如果我们不返回对象而是返回null或者其他类型的会是什么效果呢

1 function Cat(name,age){
2        var Cat = {};
3        Cat.name=name;
4        Cat.age=age;
5        return undefined//或者null 123 '123'等非对象;
6 }
7 console.log(new Cat('miaomiao',18));//Cat{}

7.其他的一律输出空对象

那么我们试着写一个类似new的函数功能

 1 function Cat(name,age){
 2    this.name=name;
 3    this.age=age;
 4 }
 5 function New(){
 6     var obj={};
 7     var res=Cat.apply(obj,arguments);
 8     return typeof res==='object'?res:obj
 9 }
10 console.log(New('mimi',18))
11 //Object {name: "mimi", age: 18}

8.这样就大功告成了么  当然不是,我们接着往下看

 1  function Cat(name,age){
 2      this.name=name;
 3      this.age=age;
 4   }
 5   Cat.prototype.sayHi=function(){
 6        console.log('hi')
 7   }
 8   function New(){
 9       var obj={};
10       var res=Cat.apply(obj,arguments);
11       return typeof res==='object'?res:obj
12   }
13 
14  console.log(new Cat('mimi',18).sayHi())
15  console.log('-------------');
16 console.log(New('mimi',18).sayHi());
17 
18 VM841:7 hi
19 VM841:15 undefined
20 VM841:16 -------------
21 VM841:17 Uncaught TypeError: New(...).sayHi is not a function(…)

9.红色的事报错,说明new操作不仅仅关注函数的本身 还关心他的原型 prototype

上面分析了那么多,现在进入正题。

  普通对象是没有prototype属性的,只有隐藏属性__proto__(IE上也有该隐藏属性,但是使用obj.__proto__不能输出东西,所以建议不要使用__proto__属性)。而函数对象则两者兼有。prototype属性指向的是函数对象的原型对象,对象的__proto__属性是创建实例对象的时候对应的函数对象的原型对象。

 1  function Cat(name,age){
 2      this.name=name;
 3      this.age=age;
 4   }
 5   Cat.prototype.sayHi=function(){
 6        console.log('hi')
 7   }
 8   function New(){
 9       var obj={};
10       obj.__proto__=Cat.prototype;
11       var res=Cat.apply(obj,arguments);
12       return typeof res==='object'?res:obj
13   }
14 
15  console.log(new Cat('mimi',18).sayHi())
16  console.log('-------------');console.log(New('mimi',18).sayHi());
17 
18 VM844:7 hi
19 VM844:16 undefined
20 VM844:17 -------------
21 VM844:7 hi
22 VM844:17 undefined
23 undefined

10.ok大功告成

原文地址:https://www.cnblogs.com/shuaihan/p/7392771.html