JavaScript中的新关键字在第一次遇到时可能会非常令人困惑,因为人们倾向于认为JavaScript不是一种面向对象的编程语言。

这是怎么一回事?它解决了什么问题?什么时候合适,什么时候不合适?


当前回答

JavaScript是一种支持面向对象编程范式的动态编程语言,用于创建对象的新实例。

对象不需要类。JavaScript是一种基于原型的语言。

其他回答

JavaScript是一种支持面向对象编程范式的动态编程语言,用于创建对象的新实例。

对象不需要类。JavaScript是一种基于原型的语言。

有时代码比文字更容易:

var func1 = function (x) { this.x = x; }                   // Used with 'new' only
var func2 = function (x) { var z={}; z.x = x; return z; }  // Used both ways
func1.prototype.y = 11;
func2.prototype.y = 12;

A1 = new func1(1);  // Has A1.x  AND  A1.y
A2 =     func1(1);  // Undefined ('this' refers to 'window')
B1 = new func2(2);  // Has B1.x  ONLY
B2 =     func2(2);  // Has B2.x  ONLY

对我来说,只要我不做原型,我就使用func2的样式,因为它给了我函数内外更多的灵活性。

new关键字更改运行函数的上下文,并返回指向该上下文的指针。

如果不使用new关键字,则运行函数Vehicle()的上下文与调用Vehicle函数的上下文相同。this关键字将引用相同的上下文。当您使用new Vehicle()时,将创建一个新上下文,因此函数中的关键字this将引用新上下文。您得到的回报是新创建的上下文。

它有三个阶段:

1.创建:它创建一个新对象,并将此对象的[[prototype]]属性设置为构造函数的prototype属性。

2.执行:它指向新创建的对象并执行构造函数。

3.返回:在正常情况下,它将返回新创建的对象。但是,如果显式返回非空对象或函数,则会返回此值。需要提及的是,如果返回非空值,但它不是对象(例如Symbol value、undefined、NaN),则忽略该值并返回新创建的对象。

function myNew(constructor, ...args) {
  const obj = {}
  Object.setPrototypeOf(obj, constructor.prototype)
  
  const returnedVal = constructor.apply(obj, args)
  
  if (
    typeof returnedVal === 'function' 
    || (typeof returnedVal === 'object' && returnedVal !== null)) {
      return returnedVal
  }
  return obj
}

有关myNew的更多信息和测试,请阅读我的博客:https://medium.com/@magenta2127/how-does-the-new-operator-work-f7eaac692026

除了丹尼尔·霍华德的回答之外,以下是new的作用(或者至少看起来是这样):

function New(func) {
    var res = {};
    if (func.prototype !== null) {
        res.__proto__ = func.prototype;
    }
    var ret = func.apply(res, Array.prototype.slice.call(arguments, 1));
    if ((typeof ret === "object" || typeof ret === "function") && ret !== null) {
        return ret;
    }
    return res;
}

虽然

var obj = New(A, 1, 2);

相当于

var obj = new A(1, 2);