面试题目:
new 操作符内部实现原理是什么?
答案解析:
new
操作符经常被用到,用面向对象语言们通用的观点来看:new
是用来实例化一个类,从而在内存中分配一个实例对象。
new
关键字会进行如下操作:
创建一个空的
JavaScript
对象(即{}
);将函数的
prototype
赋值给对象的proto
属性 ;调用函数,并将步骤1新创建的对象作为函数的
this
上下文 ;如果该函数没有返回值或者返回值不是对象,则返回创建的对象,如果返回值是对象,则直接返回该对象。
示例:
function Person(name) {
this.name = name;
}
function Person2(name) {
this.name = name;
return this.name;
}
function Person3(name) {
this.name = name;
return new Array();
}
function Person4(name) {
this.name = name;
return new String(name);
}
function Person5(name) {
this.name = name;
return function() {};
}
var person = new Person('John'); // {name: 'John'}
var person2 = new Person2('John'); // {name: 'John'}
var person3 = new Person3('John'); // []
var person4 = new Person4('John'); // 'John'
var person5 = new Person5('John'); // function() {}
Person
本身是一个普通函数,当通过new
来创建对象时,Person
就是构造函数了。
JS引擎执行这句代码时,在内部做了很多工作,用伪代码模拟其工作流程如下:
new Person("John") = {
var obj = {};
obj.__proto__ = Person.prototype; // 此时便建立了obj对象的原型链:obj->Person.prototype->Object.prototype->null
var result = Person.call(obj,"John"); // 相当于obj.Person("John")
return typeof result === 'object' ? result : obj; // 如果无返回值或者返回一个非对象值,则将obj返回作为新对象
}
延伸
原型链是面试中必考题目,new
和原型链经常一起出现,看下面这道题目:
function Parent(name) {
this.name = name;
}
var child = new Parent('前端名狮');
console.log(Parent.prototype); // {constructor: function Parent(name){this.name = name}}
console.log(child.prototype); // undefined
JavaScript 中,万物皆对象!但对象也是有区别的。分为普通对象和函数对象,Object ,Function 是JS自带的函数对象。prototype
。注:普通对象没有prototype
,但有__proto__
属性。
Parent
是函数对象,Parent.prototype
是存在的。
由上面的new
操作符的工作原理,我们知道它返回的是一个普通对象{}
,所以它是没有prototype
属性的,输出undefined
扫一扫 关注我的公众号【前端名狮】,更多精彩内容陪伴你!