原有New的方法
function Dog(name) {
this.name = name;
}
Dog.prototype.bark = function () {
console.log('wangwang');
}
Dog.prototype.sayName = function () {
console.log('my name is ' + this.name);
}
let sanmao = new Dog('三毛');
sanmao.sayName();
sanmao.bark();
手撕New源码
首先也会把其当做普通函数执行
- 1.浏览器会默认创建一个实例对象「对象 && 对象.proto===Dog.prototype」
- 2.让方法执行的时候,方法中的this指向这个实例对象
3.所以 构造函数体中出现的 this.xxx=xxx 都是给实例对象设置的私有属性和方法
4.看函数的返回值,如果没有写或者返回的是原始值类型的值,则默认把实例对象返回;如果函数自己返回的是一个对象(含函数)则以自己返回的为主
// Ctor:constructor 需要创建实例的类
// params:数组中存储后期需要传递给Ctor的所有实参
// 方法目的:重写内置new,实现创造Ctor这个类的一个实例
function _new(Ctor, ...params) {//剩余运算符
// 1.创建一个实例对象
/* let obj = {};
obj.__proto__ = Ctor.prototype; */
let obj = Object.create(Ctor.prototype);
// 2.把方法执行,让方法中的this指向这个实例对象 call改变函数中的this
let result = Ctor.call(obj, ...params),//展开运算符
type = typeof result;
// 3.看方法执行的返回值:如果返回的是原始值或者没有写返回值,我们把创建的实例对象返回,如果函数自己返回个对象(含函数),则以自己返回的为主
if (result !== null && (type === "object" || type === "function")) return result;
return obj;
}
let sanmao = _new(Dog, '三毛');
sanmao.bark(); //=>"wangwang"
sanmao.sayName(); //=>"my name is 三毛"
console.log(sanmao instanceof Dog); //=>true
// Object.create(obj):创建一个空对象,并且把obj作为它的原型「空对象.__proto__===obj」
// + obj必须是一个对象或者null
// + Object.create(null) 创建一个空对象,但是没有__proto__
…运算符
- 实参中的
...
是展开运算符 - 形参中的
...
是剩余运算符