学习一下 JS中的 new

40 阅读2分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第 18 天,点击查看活动详情

1.mdn官方解释

new 运算符创建一个用户定义的对象类型的实例或具有构造函数的内置对象的实例。

看起来有点复杂没关系

2.new运算符 做了什么

  1. 创建一个新对象。
  2. 把这个新对象的__proto__属性指向 原函数的prototype属性。(即继承原函数的原型)
  3. 将这个新对象绑定到 此函数的this上
  4. 返回新对象,如果这个函数没有返回其他对象

3.new Foo()发生了什么

  1. 一个继承自 Foo.prototype 的新对象被创建。
  2. 使用指定的参数调用构造函数 Foo,并将 this 绑定到新创建的对象。new *Foo* 等同于 new Foo(),也就是没有指定参数列表,Foo 不带任何参数调用的情况。
  3. 由构造函数返回的对象就是 new 表达式的结果。如果构造函数没有显式返回一个对象,则使用步骤 1 创建的对象。(一般情况下,构造函数不返回值,但是用户可以选择主动返回对象,来覆盖正常的对象创建步骤)

4.到底怎么理解new,记不住怎么办?

  1. new创建了一个对象A。
  2. 对象A的隐式原型指向函数的显式原型(foo.prototype)
  3. 函数的this指向这个对象A && 运行函数
  4. new foo() 返回结果 ,函数有返回对象,结果=》这个对象; 函数没有返回对象,结果=》new出来的对象A。

5.手写一个功能类似于new的函数

好吧,到现在为止我算是彻底理解new关键词干嘛的了。俗话说的好,找不到女票,可以给自己new一个对象。

通过new运算符,我们可以得到一个对象。^_^

来手写一个功能类似于new函数加深理解!!!!为了方便理解,模拟的步骤 一一对应 章节四的内容

function Tomato(name) {
  this.name = name
  this.title = '我这次真的理解new是干嘛的了'
}

var s1 = new Tomato('小番茄')
console.log(s1) //  { name: '小番茄', title: '我这次真的理解new是干嘛的了' }

// 这里就以函数的形式模仿 new的作用
function myNew() {
  // 获取一下函数的传参 !!这个地方和平时的 slice 不一样,这里使用的是shift,shhift会去除原数组第一个元素,并返回第一个元素。
  var fn = Array.prototype.shift.call(arguments)

  // 1.创建一个对象
  var obj = new Object()

  // 2.修改对象的隐式原型属性指向 函数的显示原型
  obj.__proto__ = fn.prototype

  // 3.函数的this指向这个对象A  && 运行函数
  let back = fn.apply(obj, arguments)

  // 4. 处理返回值
  return typeof back === 'object' ? back : obj
}

myNew(Tomato, 1, 2, 3, 4, 5)

end

  • 最后补充别人写的简化形式
function _new(fn, ...arg) {
    const obj = Object.create(fn.prototype);
    const ret = fn.apply(obj, arg);
    return ret instanceof Object ? ret : obj;
}