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 一个实例要做哪些操作了吗?看似简单的一个运算符,背后实现起来并没有那么简单,需要细细品味才得要义。


相关文章
|
3月前
|
JavaScript 前端开发 Java
【面试题】new 一个对象时,js 做了什么?
【面试题】new 一个对象时,js 做了什么?
|
4月前
|
中间件
在 Egg.js 应用中,你可以通过 `this` 关键字来获取上下文
在 Egg.js 应用中,你可以通过 `this` 关键字来获取上下文
36 1
|
26天前
|
JavaScript 前端开发 开发者
js开发:请解释什么是ES6的let和const关键字,以及它们与var关键字的区别。
ES6引入`let`和`const`替代`var`声明变量。`let`有块级作用域,存在暂时性死区,不进行变量提升,可重新赋值。`const`用于常量,值不可变但引用类型内容可变,同样有块级作用域和暂时性死区。与`var`主要区别在于作用域、变量提升和可变性。这些改进提高了代码的可预测性和安全性。
24 2
|
27天前
|
JavaScript 前端开发
js开发:请解释this关键字在JavaScript中的用法。
JavaScript中的`this`关键字根据执行上下文指向不同对象:全局作用域中指向全局对象(如`window`),普通函数中默认指向全局对象,但作为对象方法时指向该对象。在构造函数中,`this`指向新实例。箭头函数不绑定`this`,而是继承上下文的`this`值。可通过`call`、`apply`、`bind`方法显式改变`this`指向。
9 2
|
1月前
|
JavaScript 前端开发 算法
JavaScript 关键字 debugger 的作用和使用场景介绍
JavaScript 关键字 debugger 的作用和使用场景介绍
29 0
|
1月前
|
JavaScript 前端开发 编译器
编程笔记 html5&css&js 077 Javascript 关键字
编程笔记 html5&css&js 077 Javascript 关键字
|
3月前
|
存储 JavaScript 前端开发
JavaScript 自定义对象 及 new()原理与实现 如何完整地手写实现new
JavaScript 自定义对象 及 new()原理与实现 如何完整地手写实现new
59 0
|
3月前
|
JavaScript 前端开发
js中new关键字的作用,new一个对象的过程中发生了什么
js中new关键字的作用,new一个对象的过程中发生了什么
|
4月前
|
JavaScript 前端开发 API
(简单详细)javascript中new url()属性,轻松解析url地址
(简单详细)javascript中new url()属性,轻松解析url地址
127 0
|
4月前
|
JavaScript 前端开发
js中new关键字的作用
js中new关键字的作用
23 0