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的样式,因为它给了我函数内外更多的灵活性。

其他回答

好吧,JavaScript本身可能因平台而异,因为它始终是原始规范ECMAScript(ES)的实现。

在任何情况下,与实现无关,所有遵循ECMAScript规范的JavaScript实现都将为您提供一种面向对象的语言。根据ES标准:

ECMAScript是一种面向对象的编程语言,用于执行计算和操纵计算对象在主机环境中。

现在我们已经同意JavaScript是ECMAScript的一种实现,因此它是一种面向对象的语言。在任何面向对象的语言中,新操作的定义都表示,这样的关键字用于从特定类型的类(包括匿名类型,例如C#)创建对象实例。

在ECMAScript中,我们不使用类,您可以从规范中了解到:

ECMAScript不使用C++、Smalltalk或Java中的类。相反,可以通过各种方式创建对象,包括通过文字符号或通过构造函数创建对象,然后执行代码,通过指定初始值初始化所有或部分对象其财产的值。每个构造函数都是一个函数属性名为―prototype‖,用于实现基于原型的继承和共享财产。对象由创建在新表达式中使用构造函数;例如,新Date(2009,11)创建一个新的Date对象。调用构造函数不使用new的结果取决于构造函数。例如,Date()生成当前日期和时间,而不是对象。

所以它可能不是为了创造对象的实例

它正是为了这个。您可以这样定义函数构造函数:

function Person(name) {
    this.name = name;
}

var john = new Person('John');

然而,ECMAScript的额外好处是您可以使用.prototype属性进行扩展,因此我们可以执行以下操作。。。

Person.prototype.getName = function() { return this.name; }

从该构造函数创建的所有对象现在都将有一个getName,因为它们可以访问原型链。

new关键字使用函数作为构造函数创建对象的实例。例如:

var Foo = function() {};
Foo.prototype.bar = 'bar';

var foo = new Foo();
foo instanceof Foo; // true

实例继承自构造函数的原型。因此,在上面的例子中。。。

foo.bar; // 'bar'

它有三个阶段:

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

JavaScript是一种面向对象的编程语言,它完全用于创建实例。它是基于原型的,而不是基于类的,但这并不意味着它不是面向对象的。