new 操作符
AprilTong 7/30/2021 Javascript
# new 操作符做了什么
- 创建的一个空的 js 对象,即就是{}
- 将空对象的原型 prototype 指向构造函数的原型
- 将空对象作为构造函数的上下文,即改变 this 的指向
- 对构造函数有返回值的判断
- 如果返回值是基础数据类型,则忽略返回值,返回 new 操作符生成的对象
- 如果返回值是引用数据类型,则使用 return 的返回,也就是操作符无效
function Person(name) {
this.name = name;
return 1;
}
let me = new Person('april');
console.log(me); // {name: 'april'}
1
2
3
4
5
6
2
3
4
5
6
function Person(name) {
this.name = name;
console.log('hahah', [].shift.call(arguments));
return { age: 12 };
}
let me = new Person('april');
console.log(me); // {age: 12}
1
2
3
4
5
6
7
2
3
4
5
6
7
# 模拟实现
new 是关键字,无法直接覆盖,定义一个函数来模拟 new 的效果
function objectFactory() {
let obj = new Object();
Constructor = [].shift.call(arguments);
obj.__proto__ = Constructor.prototype;
let result = Constructor.apply(obj, arguments);
// typeof null 返回的也是object
return typeof result === 'object' ? result || obj : obj;
}
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
# 模拟方法使用
function Person(name) {
this.name = name;
}
let result = objectFactory(Person, 'april');
console.log(result); // { name: 'april'}
1
2
3
4
5
2
3
4
5
# 注意
三种创建空对象的区别
所以由 Object.create 生成的对象,调用原型上的方法会报错
function objectFactory() {
let obj = Object.create(null);
Constructor = [].shift.call(arguments);
obj.__proto__ = Constructor.prototype;
let result = Constructor.apply(obj, arguments);
// typeof null 返回的也是object
return typeof result === 'object' ? result || obj : obj;
}
function Person(name) {
this.name = name;
}
Person.prototype.say = function() {
console.log('hello');
};
let result = objectFactory(Person, 'april');
result.say(); // Uncaught TypeError: result.say is not a function
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16