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是一种面向对象的编程语言,它完全用于创建实例。它是基于原型的,而不是基于类的,但这并不意味着它不是面向对象的。

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

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

JavaScript不是面向对象编程(OOP)语言。因此,JavaScript中的查找过程使用委托过程,也称为原型委托或原型继承。

如果您试图从一个没有的对象中获取属性的值,JavaScript引擎会查找该对象的原型(以及它的原型,一步一步)。它是原型链,直到链结束为null,即Object.prototype==null(标准对象原型)。

此时,如果未定义属性或方法,则返回undefined。

重要的函数是一类对象。

函数=函数+对象组合框

FunctionName.prototype={共享子对象}

{
  // other properties
  prototype: {
   // shared space which automatically gets [[prototype]] linkage
      when "new" keyword is used on creating instance of "Constructor
      Function"
  }
}

因此,使用新关键字。,

手动创建对象,例如newObj。使用JavaScript规范[[prototype]](即proto)中的proto(AKA:dunderproto)创建隐藏键引用并将财产分配给newObj返回newObj对象。

所有操作都是手动完成的。

function CreateObj(value1, value2) {
  const newObj = {};
  newObj.property1 = value1;
  newObj.property2 = value2;
  return newObj;
}
var obj = CreateObj(10,20);

obj.__proto__ === Object.prototype;              // true
Object.getPrototypeOf(obj) === Object.prototype // true

JavaScript关键字new有助于自动化此过程:

创建了一个新的对象文本,其标识如下:{}引用并为此分配财产隐藏键创建[[prototype]](即proto)到Function.prototype共享空间。此对象{}的隐式返回

function CreateObj(value1, value2) {
  this.property1 = value1;
  this.property2 = value2;
}

var obj = new CreateObj(10,20);
obj.__proto__ === CreateObj.prototype             // true
Object.getPrototypeOf(obj) == CreateObj.prototype // true

调用不带new关键字的构造函数:

=>此:窗口

function CreateObj(value1, value2) {
  var isWindowObj = this === window;
  console.log("Is Pointing to Window Object", isWindowObj);
  this.property1 = value1;
  this.property2 = value2;
}
var obj = new CreateObj(10,20); // Is Pointing to Window Object false
var obj = CreateObj(10,20); // Is Pointing to Window Object true
window.property1; // 10
window.property2; // 20

有时代码比文字更容易:

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

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

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

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

var john = new Person('John');

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

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

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