理解new运算符

127 阅读1分钟

new操作符

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

new一个构造函数具体做了什么

  1. 创建一个新对象obj
  2. 将构造函数的原型prototype指向新对象obj的__proto__属性。
  3. 构造函数中的this指向新对象obj,并且执行构造函数。
  4. 如果构造函数无返回值,或者返回值不是引用类型,则返回新对象;否则为构造函数的返回值。

new F()

function F(name, age) {
    this.name = name;
    this.age = age;
}

function F1(name, age) {
    this.name = name;
    this.age = age;
    return null;
}

function F2(name, age) {
    this.name = name;
    this.age = age;
    return 1;
}

function F3(name, age) {
    this.name = name;
    this.age = age;
    return { a: 1 };
}

function F4(name, age) {
    this.name = name;
    this.age = age;
    return function A () {};
}

let obj = new F('wwx', 30);
console.log(obj); // F { name: 'wwx', age: 30 }

let obj = new F1('wwx', 30);
console.log(obj); // F1 { name: 'wwx', age: 30 }

let obj = new F2('wwx', 30);
console.log(obj); // F2 { name: 'wwx', age: 30 }

let obj = new F3('wwx', 30);
console.log(obj); // { a: 1 }

let obj = new F4('wwx', 30);
console.log(obj); // function A() {}

模拟实现new函数

function newFn() {
  // 1.创建一个新的对象
  let obj = new Object();
  // 2.拿到arguments中的第一项,即构造函数
  let constructor = [].shift.call(arguments);
  // 3.将新对象的__proto__属性指向构造函数的原型
  obj.__proto__ = constructor.prototype;
  // 4.执行构造函数
  let reVal = constructor.apply(obj, arguments);
  // 5.需要判断构造函数的返回值来确定本函数的返回结果,对象和函数除外,都返回obj
  return 
    typeof reVal === 'object' || typeof reVal === 'function' ? reVal : obj;
}

function Fn(name, age) {
  this.name = name;
  this.age = age;
}

var f = newFn(Fn, 'wwx', 30);
console.log(f); // Fn { name: 'wwx', age: 30 }
console.log(f.name); // 'wwx'
console.log(f.age); // 30

参考

JavaScript高级程序设计(第三版)

一道面试题引发的思考:理解 new 运算符

前端面试之手写代码