在这里简单介绍一下new方法,以及手动实现一个new方法。
new的作用
常言道,没有对象怎么办? new一个!
new主要是用来构造对象的,下面来一个例子:
function Person(name, age) {
this.name = name;
this.age = age;
}
let p = new Person('yan', 18);
上面的例子中,我们可以使用new运算符作用于一个函数上,构造出一个对象。
new出来对象的__proto__属性
在控制台打印下上面例子中的p,可以看到,对象的__proto__指向了其构造函数的prototype属性
p.__proto__ === Person.prototype //true
上面的代码也可以验证这个理论
构造函数的return
下面来几个例子
//0. 构造函数没有用return直接返回
function Person(name, age) {
this.name = name;
this.age = age;
}
let p = new Person('yan', 18);
console.log(p); //Person {name: "yan", age: 18}
//1. return基本类型
function Person(name, age) {
this.name = name;
this.age = age;
return 1;
}
let p = new Person('yan', 18);
console.log(p); //Person {name: "yan", age: 18}
//2.return 对象
function Person(name, age) {
this.name = name;
this.age = age;
return {};
}
let p = new Person('yan', 18);
console.log(p.name); //undefined
从上面的例子中,可以看出: 如果该函数没有返回对象,则返回this
实现new
更多new方法的详细介绍,可以参考mdn上的文档,其中文档上说new 关键字会进行如下的操作:
- 创建一个空的简单JavaScript对象(即{};
- 链接该对象(设置该对象的constructor)到另一个对象,即 protp === fn.prototype;
- 绑定this;
- 返回值的确定
以上几点我们也得到了证实,下面根据上面几点,我们来实现一个new方法:
function myNew() {
// 拿到要作用的构造函数和参数
let [constructor, ...args] = [... arguments];
// 简单处理下箭头函数不可以作为构造函数
if(constructor.toString().includes('=>')) {
throw '箭头函数不能作为构造函数';
}
//0. 创建一个空对象
let obj = {};
//1. 将对象的原型指向构造函数中的prototype属性
obj.__proto__ = constructor.prototype;
//2. 绑定this指向
let res = constructor.apply(obj, args);
//3. 返回值问题,如果该函数没有返回对象,则返回this
return res instanceof Object ? res : obj;
}
//简单验证下
function Person(name, age) {
this.name = name;
this.age = age;
return 1;
}
let p = myNew(Person,'yan', 18); //Person {name: "yan", age: 18}
这样,就简单实现了一个new方法。
instanceof
上面我们手写new方法的时候,用到了一个方法instanceof,这里对其做个简单介绍:
作用
instanceof 运算符用于检测构造函数的 prototype 属性是否出现在某个实例对象的原型链上。要记住,是原型链上!
function Preson(){}
function User(){}
var p = new Preson();
p instanceof Preson; // true,因为 Object.getPrototypeOf(p) === C.prototype
p instanceof User; // false
p instanceof Object; // true,因为 Object.prototype.isPrototypeOf(p) 返回 true
Preson.prototype instanceof Object // true,同上
语法
object instanceof constructor
- object 某个实例对象
- constructor 某个构造函数
手动实现
/**
* 如果对象和构造函数的原型链顶端一致,则返回true,否则返回false
*/
function myInstanceOf(object, constructor) {
//构造函数的protype
const baseProto = constructor.prototype;
//原型链顶端
const topProto = Object.__proto__;
while(topProto !== null){
if(topProto === baseProto){
return true
}else {
topProto = topProto.__proto__
}
}
return false
}