Bootstrap

JavaScript 的new操作符详解、实现

  • MDN定义:new 运算符创建一个用户定义的对象类型的实例或具有构造函数的内置对象的实例。
  • 预备知识:js原型/原型链,明白这个有助于理解new的来龙去脉

new关键字会进行如下操作

  1. 创建一个空对象
  2. 链接该对象(设置该对象的constructor)到另一个对象(Person)
  3. 将步骤1创建的对象作为this的上下文
  4. 如果该函数没有返回新对象(person1),则返回this
// 返回this的情况
function f () { console.log(1) }
let a = new f() // 1,此时有输出,因为用new时调用了f函数
a // f (),a指向构造函数函数f

用new创建对象时

  • 比如new fun()执行时
  1. 一个继承自fun.prototype的新对象被创建
  2. 使用指定的参数调用构造函数fun,并将this绑定到新对象(指定新对象的上下文)
  3. 由构造函数返回的对象就是new表达式的结果。如果构造函数没有显式返回一个对象,则使用步骤1创建的对象
  • 特别注意:“继承自fun.prototype” 和 “调用函数fun” 的确是两个概念,前者是说从fun函数的原型对象取得相应的属性和方法,后者是从函数体本身取得~,不清楚的话可以参考原型链的 “原型对象” 等概念 。
  • 什么叫没有显式返回呢?举个例子
function Car () {} // 函数体未返回对象
let a = new Car()
a // Car{},赋值给a一个继承自Car.prototype的对象

实现new

function otherNew (a, ...args) { // ...args,剩余参数,且args是个数组
	let obj = {} // 创建空对象
	obj.__proto__ = a.prototype // 让空对象的原型指向a的原型(继承)
	const res = a.apply(obj, args) // 让obj指向a
	// ^n:匹配任何开头为n的字符串,n$:匹配任何结尾为n的字符串
	// 构造函数返回的是则返回对象
	if (/^(object | function)$/.test(typeof res)) return res
	return obj // 否则返回实例
}

// 测试是否实现
function Person (name) {
  this.name = name
}

Person.prototype.age = "20" // 在Person的原型上加个属性age

let b = otherNew(Person, "张飞") // 形式上差了点,意思就是这个意思

console.log(b)       // Person { name: '张飞' }
console.log(b.name)  // 张飞
console.log(b.age)   // 20

如果觉得对你有帮助的话,点个赞呗~

反正发文又不赚钱,交个朋友呗~

如需转载,请注明出处foolBirdd


2021.3.24更新,讲清实现new中的this指向

;