js基础之new关键字知多少

简介: 一个问题:写一个js方法实现一个 new 运算符。new 都用过,用来创建实例对象,可new 操作背后都做了些什么,我们确很少关注。

new 操作背后


new 运算符创建一个用户定义的对象类型的实例或具有构造函数的内置对象的实例。new 关键字会进行如下的操作:


1、创建一个空的简单JavaScript对象(即{});


2、链接该对象(即设置该对象的构造函数)到另一个对象 ;


3、将步骤1新创建的对象作为this的上下文 ;


4、如果该函数没有返回对象,则返回this。


以上是 MDN 的原文,通过上面描述,我们能比较清晰的了解到一个简单new运算符背后做了些什么。现在我们来看看下面这段代码


function Car(make, model, year) {
  this.make = make;
  this.model = model;
  this.year = year;
}
Car.prototype={
  getMake: function() {
    return this.make
  }
}
var car = new Car('Eagle', 'Talon TSi', 1993)


我们来分解一下 var car = new Car('Eagle', 'Talon TSi', 1993)这行代码

第一步:创建一个简单空对象


var obj = {}


第二步:链接该对象到另一个对象(原型链)


// 设置原型链
obj.__proto__ = Car.prototype


第三步:将步骤1新创建的对象作为 this 的上下文


// this指向obj对象
Car.apply(obj, ['Eagle', 'Talon TSi', 1993])


第四步:如果该函数没有返回对象,则返回this


// 因为 Car() 没有返回值,所以返回obj
var car = obj
car.getMake() // 'Eagle'


需要注意的是如果 Car()return 则返回 return的值


var rtnObj = {}
function Car(make, model, year) {
  // todo
  // ...
  //返回一个对象
  return rtnObj
}
var car = new Car('Eagle', 'Talon TSi', 1993)
console.log(car === rtnObj) // true


封装一个方法


现在我们把上面的步骤封装成一个对象实例化方法


function objectFactory(){
    var obj = {};
    //取得该方法的第一个参数(并删除第一个参数),该参数是构造函数
    var Constructor = [].shift.apply(arguments);
    //将新对象的内部属性__proto__指向构造函数的原型,这样新对象就可以访问原型中的属性和方法
    obj.__proto__ = Constructor.prototype;
    //取得构造函数的返回值
    var ret = Constructor.apply(obj, arguments);
    //如果返回值是一个对象就返回该对象,否则返回构造函数的一个实例对象
    return typeof ret === "object" ? ret : obj;
}


class


es6 中新增加了关键字 class ,如果把上面 function 换成 class 结果会怎样呢?其实结果是一样的。


class Car {
  constructor(make, model, year) {
    this.make = make;
    this.model = model;
    this.year = year;
  }
  getMake() {
    return this.make
  }
}
var car = objectFactory(Car, 'Eagle', 'Talon TSi', 1993)
car.getMake() // 'Eagle'


小结


现在你明白 js 中 new 一个实例要做哪些操作了吗?看似简单的一个运算符,背后实现起来并没有那么简单,需要细细品味才得要义。


相关文章
|
4月前
|
JavaScript
ES6学习(9)js中的new实现
ES6学习(9)js中的new实现
|
2月前
|
JavaScript 前端开发 安全
ECMAScript 6(以下简称 ES6)的出现为 JavaScript 带来了许多新的特性和改进,其中 let 和 const 是两个非常重要的关键字。
ES6 引入了 `let` 和 `const` 关键字,为 JavaScript 的变量管理带来了革新。`let` 提供了块级作用域和暂存死区特性,避免变量污染,增强代码可读性和安全性;`const` 用于声明不可重新赋值的常量,但允许对象和数组的内部修改。两者在循环、函数内部及复杂项目中广泛应用,有助于实现不可变数据结构,提升代码质量。
32 5
|
2月前
|
设计模式 JavaScript 前端开发
js中new和object.creat区别
【10月更文挑战第29天】`new` 关键字和 `Object.create()` 方法在创建对象的方式、原型链继承、属性初始化以及适用场景等方面都存在差异。在实际开发中,需要根据具体的需求和设计模式来选择合适的方法来创建对象。
|
2月前
|
前端开发 JavaScript 开发者
除了 async/await 关键字,还有哪些方式可以在 JavaScript 中实现异步编程?
【10月更文挑战第30天】这些异步编程方式在不同的场景和需求下各有优劣,开发者可以根据具体的项目情况选择合适的方式来实现异步编程,以达到高效、可读和易于维护的代码效果。
|
4月前
|
JavaScript 前端开发 Java
JavaScript 保留关键字
JavaScript 保留关键字
28 2
|
4月前
|
JavaScript 前端开发
JavaScript this 关键字
JavaScript this 关键字
19 1
|
5月前
|
JavaScript 前端开发
JavaScript 语句标识符(关键字)
【8月更文挑战第29天】
31 5
|
5月前
|
JavaScript 前端开发
|
7月前
|
JavaScript 前端开发 开发者
JavaScript中的const关键字解析
JavaScript中的const关键字解析
|
7月前
|
JavaScript 前端开发
JavaScript变量命名规则及关键字详解
JavaScript变量命名规则及关键字详解
108 1