• 主页
  • 个人简介
    • 圣墨 photo

      圣墨

      一个爱折腾,有诗有远方的人

    • Learn More
    • Github
    • Cnblogs
    • Weibo
  • 文章
    • 所有文章
    • 所有标签
  • Html&Css
  • Javascript
  • 设计模式
  • 前端性能优化
  • 原生实现专题
  • 数据结构与算法
  • Book
  • 面试题
  • 前端工具
  • 随记

new 运算符

26 Jun 2019

Reading time ~1 minute

new

1、认识new运算符


// 1、创建一个构造函数
function Animal(name) {
    this.name = name;
}

Animal.color = 'red';
Animal.prototype.say() = function() {
    console.log('my name is ' + this.name)
}

// 2、通过new来实例化一个对象

const cat = new Animal('cat');
cat.name; // => cat
cat.say(); // => my name is cat

有上述代码我们可以了解到,通过new运算符,我们可以根据构造函数创建一个实例,并继承这个实例的原型方法,new存在的意义在于它实现了javascript中的继承,而不仅仅是实例化了一个对象!那么new关键字具体干了什么呢?

2、new 做了如下操作


    1、创建了一个空对象
    2、链接到原型(空对象的`__proto__`成员指向构造对象`prototype`成员对象)
    3、改变this的指向,让this指向新创建的实例对象
    4、返回一个新对象

用伪代码模拟其工作流程如下:


    new Animal('cat') =function() {
        // 1、创建一个空对象
        var obj = {};

        // 2、链接到原型
        obj.__proto__ = Animal.prototype;

        // 3、改变this的指向,让this指向新创建的实例对象
        var result = Animal.call(obj, 'cat')

        // 4、返回一个新对象
        return typeof result === 'object'? result : obj;
    }

new 通用流程


function myNew() {
    //1、创建一个空对象
    const obj = {}

    //2、取出参数第一个构造函数
    const contructor = [].shift.call(arguments);
    // 3、链接到原型
    obj.__proto__ = contructor.prototype;

    // 4、改变this的指向
    const result = contructor.apply(obj,arguments);

    // 5、返回一个新对象
    return typeof result === 'object'? result : obj;
}

3、对于 new 来说,还需要注意下运算符优先级。


    function Foo() {
        return this;
    }
    Foo.getName = function () {
        console.log('1');
    };
    Foo.prototype.getName = function () {
        console.log('2');
    };

    new Foo.getName();   // -> 1
    new Foo().getName(); // -> 2

从上图可以看出,new Foo() 的优先级大于 new Foo ,所以对于上述代码来说可以这样划分执行顺序


    new (Foo.getName());
    (new Foo()).getName();

对于第一个函数来说,先执行了 Foo.getName() ,所以结果为 1;对于后者来说,先执行 new Foo() 产生了一个实例,然后通过原型链找到了 Foo 上的 getName 函数,所以结果为 2。



javascript  微博  QQ  朋友圈