• 深入理解new运算符


    在 JavaScript 中,new 运算符创建一个用户定义的对象类型的实例或具有构造函数的内置对象的实例。创建一个对象很简单,为什么我们还要多此一举使用 new 运算符呢?它到底有什么样的魔力?

    认识 new 运算符

    通过下面的例子理解 new 运算符:

    function Person (name) {
      this.name = name
    }
    
    Person.prototype.getName = function () {
      console.log(this.name)
    }
    
    var joe = new Person('joe')
    
    joe.sayHello = function () {
      console.log('Hello!')
    }
    
    joe.getName() // joe
    joe.sayHello() // Hello!
    
    Person.sayHello() // Uncaught TypeError: Person.sayHello is not a function
    

    Person 是一个普通的函数,当它与 new 运算符一起使用时,Person 就是一个构造函数。通过 new Person('joe') 得到的新对象 joe 继承了 Person 的属性,同时,this 也指向 joe 实例。为 joe 添加的属性 sayHello 不会影响 Person,即 joe 是区别与 Person 的一个新对象。

    因此,通过 new 创建的实例对象和构造函数之间建立了一条原型链,并通过原型链赋予实例对象继承属性的能力

    广州设计公司https://www.houdianzi.com 我的007办公资源网站https://www.wode007.com

    new 的原理和实现

    通过上面的分析,new 运算符内部做了如下四个操作:

    • 创建一个空的简单 JavaScript 对象(即{});
    • 链接新对象(即设置该新对象的构造函数)到函数对象;
    • 将新创建的对象作为 this 的上下文;
    • 如果该函数没有返回对象,返回新创建的对象。

    new 的实现如下:

    function newOperator (ctor, ...args) {
      var obj = {};
      obj.__proto__ = ctor.prototype
      var res = ctor.apply(obj, args)
      return res || obj;
    }
    

    优化一下代码:

    function newOperator (ctor, ...args) {
      var o = Object.create(ctor.prototype) // 合并第一和第二步:创建一个空的简单 JavaScript 对象(即{}),链接新对象(即设置该新对象的构造函数)到函数对象
      return fn.apply(o, args) || o
    }
    

    使用 newOperator 函数测试上面 Person 的例子:

    function Person(name) {
      this.name = name
    }
    
    Person.prototype.getName = function () {
      console.log(this.name)
    }
    
    var joe = newOperator(Person, 'joe')
    
    joe.sayHello = function () {
      console.log('Hello!')
    }
    
    joe.getName() // joe
    joe.sayHello() // Hello!
    
    Person.sayHello() // Uncaught TypeError: Person.sayHello is not a function
    

    结果是一致的。

    更好的检查方式是:

    function Person(name) {
      this.name = name
    }
    
    console.log(new Person('joe')) // @1
    console.log(newOperator(Person, 'joe')) // @2
    

    @1 和 @2 在控制台的显示信息是一模一样的。

  • 相关阅读:
    Vue-基础(四)
    Vue-基础(三)
    Vue-基础(一)
    Vue-基础(二)
    CSS-初始化模板2(common.css)
    CSS-初始化模板1(normalize.css)
    CSS预处理器-Less
    MySQL视窗函数row_number(), rank(), denser_rank()
    LeetCode第4题:寻找两个有序数组的中位数
    无重复字符的最长子串
  • 原文地址:https://www.cnblogs.com/xiaonian8/p/13847217.html
Copyright © 2020-2023  润新知