Skip to content

Latest commit

 

History

History
79 lines (57 loc) · 1.93 KB

10.new的模拟实现.md

File metadata and controls

79 lines (57 loc) · 1.93 KB

new

一句话介绍new:

new运算符创建一个用户定义的对象类型的实例或具有构造函数内置对象类型之一

function Person (name,age){
    this.name = name;
    this.age = age;

    this.habit = 'Games';
}

Person.prototype.gender = 'man';

Person.prototype.sayName = function () {
    console.log(`I am ${this.name}`);
}

let person = new Person('kevin',18);

console.log(person.name); // kevin
console.log(person.habit); // Games
console.log(person.gender); // man

person.sayName() // I am kevin
  1. 实例person访问Person构造函数里的属性
  2. 实例person可以访问Person.prototype里的属性

初步实现

new 的结果是一个新对象,所以我们要先建立一个新对象

// 第一版
function objectFactory () {
    let obj = new Object();
    // 取出第一个参数,就是我们要传入的构造函数
    // shift会改变原数组,所以arguments会被去除第一个参数
    Constructor = Array.prototype.shift.call(arguments);
    // 将obj的原型指向构造函数
    // obj就可以访问构造函数原型中的属性
    obj.__proto__ = Constructor.prototype;
    // 将构造函数的this指向新建的对象
    // 这样obj就可以访问构造函数中的属性
    Constructor.apply(obj,arguments);

    return obj
}

返回值效果的实现

// 最终版
function objectFactory() {

    //从Object.prototype上克隆一个对象
    var obj = new Object();

    //取得外部传入的构造器
    Constructor = [].shift.call(arguments);

    //指向正确的原型
    var F=function(){};
    F.prototype= Constructor.prototype;
    obj=new F();

    //借用外部传入的构造器给obj设置属性
    var ret = Constructor.apply(obj, arguments);

    //确保构造器总是返回一个对象
    return typeof ret === 'object' ? ret || obj : obj;

};