五分钟快速理解new操作符
(1)new操作符做了哪些事情(4步)
-
新建一个新的空对象{}
-
让空对象的__proto__和构造函数的prototype建立链接
{ _proto:Person.prototype }
-
改变this指向,让构造函数中的this指向这个新的对象
{ _proto:Person.prototype, age:11, name:"jack", ... }
-
对构造函数的返回值类型进行判断
如果返回值类型为基本数据类型(不返回值相当于return undefined),new 操作符会返回新创建的对象实例;
如果返回值类型是引用数据类型,则该引用数据会成为 new 表达式的结果,而新创建的对象实例会被丢弃;
(2)代码示例
-
不返回数据
function Person1(age,name){ this.age=age; this.name=name; //不返回值相当于return undefined } let person1=new Person1(11,"jack"); console.log(person1)//{age: 11, name: 'jack'}
-
返回基本数据类型
function Person2(age,name){ this.age=age; this.name=name; return 12;//基本数据类型 } let person2=new Person2(16,"mike"); console.log(person2)//{age: 16, name: 'mike'}
-
返回引用数据类型
function Person3(age,name){ this.age=age; this.name=name; return [1,2,3];//引用数据类型 } let person3=new Person3(18,"jmy"); console.log(person3)//[1, 2, 3] function Person4(age,name){ this.age=age; this.name=name; return {age:1,name:"chourunfat"};//引用数据类型 } let person4=new Person4(20,"bob"); console.log(person4)//{age: 1, name: 'chourunfat'}
(3)手写new标识符
-
封装new标识符
function customNew(func,...params){ //新建一个空对象 let obj={}; //将空对象的原型和构造函数的原型连接起来 Object.setPrototypeOf(obj,func.prototype) //改变this执行 let result=func.call(obj,...params) return result instanceof Object ? result : obj; }
-
测试使用
function func1(a,b,c){ this.a=a; this.b=b; } const obj1= customNew(func1,1,2,3); console.log(obj1)//{a: 1, b: 2} function func2(a,b,c){ this.a=a; this.b=b; return { name:"111" } } const obj2= customNew(func2,1,2,3); console.log(obj2)//{name: '111'}