new 的实现过程 es5 es6类的对比

1、 手写new的实现过程

主要实现步骤:

  1. 生成一个新对象
  2. 为这个对象设置prototype
  3. 使用this执行构造函数
  4. 返回这个对象
function _new() { 
    // 1.生成一个新对象 
    let obj= {}; 

    // 第一个参数是构造函数 
    let [Fn, ...args] = [...arguments]; 
    // 2.为这个对象设置prototype;实际上就是生产了一个新的上下文 
    obj.__proto__ = Fn.prototype; 
    // 3.使用apply在obj作用域中调用构造器函数,属性和方法被添加到 this 引用的对象即obj中 
    let result = Fn.apply(obj, args); 
    if (result && (typeof (result) == "object" || typeof (result) == "function")) { 
        // 如果构造函数执行的结果返回的是一个对象,那么返回这个对象 
        return result; 
    } 
    // 4.如果构造函数返回的不是一个对象,返回创建的新对象 
    return obj; 
} 
var person1=_new(Person, 20) // 相当于  var person1 = new Person(20); 

2、es5和es6中类的对比

静态、私有变量等, 定义实现的对比

es5
function Point(){ 
    // 私有变量 
    var num = 10;  
    // 定义获取私有变量的方法 在原型上不能直接获取私有变量 
    this.getNum = function(){ 
        return num; 
    }   
    // public
    this.x = x;          //x,y定义在对象自身上面 
    this.y = y; 
} 
Point.prototype.add = function(){ 
    console.log(this.x + this.y); 
    console.log(this.getNum()); // 获取私有变量 这里this.num直接获取不了 使用闭包返回数据 
} 
//静态属性 
Person.total = 0;  
//静态方法 
Point.counter = function(){   
    return 'staticFn'; 
} 
var p = new Point(2, 3); 
p.add();  //输出5 1 0 
es6
class Point{ 
  constructor(x, y) {    //相当于java中的构造函数,如果不写默认为空 
    // public
    this.x = x;          //x,y定义在对象自身上面 
    this.y = y; 
  } 
  // 私有属性 es2020 
  #num = 10; 
  //静态属性 
  static total = 0; 
  //静态方法  
  static counter(){ 
      return 'staticFn'; 
  } 
  add() {                //该方法定义在Point.prototype上 
    console.log(this.x + this.y); 
    // 访问私有属性 
    console.log(this.#num);  
  } 
} 
var p = new Point(2, 3); 
p.add();  //输出5  10 

3、ES6中当函数用new关键词的时候,增加了new.target属性来判断当前调用的构造函数

1、可以限制函数的调用,比如一定要用new命令来调用

function Person(name){ 
    if(new.target === Person){ 
        this.name = name; 
    } 
    else{ 
        throw new Error('必须用new生成实例'); 
    } 
} 

2、限制类的调用方法,判断new.target是不是未定义。写出只能被继承使用的类。

class Shape { 
  constructor() { 
    if (new.target === Shape) { 
      throw new Error('本类不能实例化'); 
    } 
  } 
} 
class Rectangle extends Shape { 
  constructor(length, width) { 
    super(); 
    // ... 
  } 
} 
var x = new Shape();  // 报错 
var y = new Rectangle(3, 4);  // 正确 

上一篇
盒子模型,行内元素边距,置换元素 盒子模型,行内元素边距,置换元素
一、 盒子模型 box-sizing: content-box;//宽度和高度分别应用到元素的内容框。在宽度和高度之外绘制元素的内边距和边框。 box-sizing: border-box;// 怪异盒子模型。 为元素设定的宽度和高度决
2020-09-09
下一篇
this 和 构造函数有return this 和 构造函数有return
一、 es5中 this 1.在普通函数中的this总是代表他的直接调用者,默认情况下指向windos 2.在严格模式下,没有直接调用者的函数中的this是undefined使用 3.call,apply,bind,thi
2020-08-11