面试之《new关键字》
一问:new关键字做了什么操作,手写一个new方法,实现new关键字的作用
二问:
// 第一题 /
function Test(){
this.name = '1';
return {name: '2'}
}
const a = new Test();
console.log(a.name) // 打印什么
/// 第二题 /
function Test2(){
this.name = '1';
return 123
}
const a = new Test2();
console.log(a.name) // 打印什么
以下是我的粗浅见解,如有问题,请大家多多指教!还望大家共同进步!
- 创建一个新对象
function Person(name) {
this.name = name;
}
var person = new Person('Alice');
- 在新对象上运行[[Prototype]]连接
Person.prototype.sayName = function() {
console.log(this.name);
};
person.sayName(); // 'Alice'
- 将构造函数的this指向新对象
// 在构造函数内部
function Person(name) {
this.name = name;
}
- 返回对象
如果构造函数没有返回对象类型Object(包括Functoin, Array, Date等),
或者构造函数返回了非原始类型值(如字符串, 数字), 则忽略返回值, 使用新创建的对象.
如果构造函数显式返回undefined或null, 则同样忽略, 使用新创建的对象.
如果构造函数返回了一个对象, 则新创建的对象会被忽略, 返回的对象会成为最终的结果. 这是重点!要考!
function Person(name) {
this.name = name;
// return undefined; // 或者任何非对象值, 结果同样
}
var person = new Person('Alice');
console.log(person.name); // 'Alice'
// **** 关键测试用例! ****
function PersonWithObject(name) {
this.name = name;
return { greeting: 'Hello' };
}
var person = new PersonWithObject('Alice');
console.log(person.name); // undefined
console.log(person.greeting); // 'Hello'
所以手写new可以这么写
function _new(constructor, ...args) {
// 第一种方法
// const obj = {};
// obj.__proto__ = constructor.prototype;
// 第二种方法
const obj = Object.create(constructor.prototype);
const res = constructor.apply(obj, args);
return ["object", "function"].includes(typeof res) ? res : obj;
}
第二问答案:
问题一:2,因为构造函数返回的是一个对象,所以直接使用返回的对象,不再构建新的对象
问题二:1,构造函数返回的不是一个对象,所以需要构造新的对象,并主动调用构造函数,构造函数会将obj.name赋值为1,所以打印出来1.