Dieser Artikel stellt hauptsächlich das Prinzip der neuen Aufruffunktion in JS vor. Er hat einen gewissen Referenzwert. Jetzt kann ich ihn mit allen teilen, die ihn benötigen.
Der Konstruktor wird häufig in JavaScript verwendet Objekt (Aufruf einer Funktion über den Operator new
), was genau passiert, wenn new
zum Aufrufen einer Funktion verwendet wird? Schauen wir uns zunächst einige Beispiele an, bevor wir erklären, was sich hinter den Kulissen abspielt.
Es gibt keine return
-Anweisung am Ende des Konstruktors. Dies ist auch die Standardsituation bei der Verwendung der Konstruktor, und es wird ein neues Objekt zurückgegeben:
function Foo(age) { this.age = age; } var o = new Foo(111); console.log(o);
Dies ist ein üblicher Prozess, bei dem der Konstruktor zum Erstellen eines Objekts verwendet wird, und was gedruckt wird, ist {age: 111}
.
Konstruktor zuletzt return
Objekttypdaten:
function Foo(age) { this.age = age; return { type: "我是显式返回的" }; } var o = new Foo(222); console.log(o);
druckt {type: '我是显式返回的'}
aus, also vorher return
Die ganze Arbeit ist vergeblich getan, und schließlich wird das Objekt hinter return
zurückgegeben.
Bedeutet das, dass die Daten nach return
zurückgegeben werden, solange am Ende des Konstruktorkörpers return
steht?
Sehen wir uns die Rückgabe grundlegender Typdaten an:
function Foo(age) { this.age = age; return 1; } var o = new Foo(333); console.log(o);
gibt {age: 333}
aus, was dasselbe ist wie ohne return
. Es weicht von den Erwartungen ab. Das Prinzip dahinter finden Sie in der folgenden Analyse.
Bei Verwendung des new
-Operators zum Erstellen von Objekten finden Sie die offizielle ES5-Dokumentation in Funktionsdefinition Die folgende Definition wird in Abschnitt 13.2.2 [[Construct]]
vorgenommen:
Wenn die [[Construct]]
interne Methode für ein Function
-Objekt F
mit einer möglicherweise leeren Liste von aufgerufen wird Argumente werden die folgenden Schritte ausgeführt:
Obj sei ein neu erstelltes natives ECMAScript-Objekt.
Alle festlegen die internen Methoden von obj, wie in 8.12 angegeben.
Setzen Sie die interne Eigenschaft [[Class]] von obj auf Object.
Setzen Sie die [[Extensible]] interne Eigenschaft von obj auf true.
Proto sei der Wert des Aufrufs der internen Eigenschaft [[Get]] von F mit dem Argument „prototype“.
Wenn Type(proto) Object ist, setzen Sie die interne Eigenschaft [[Prototype]] von obj auf proto.
Wenn Type(proto) nicht Object ist, setzen Sie die interne Eigenschaft [[Prototype]] von obj auf das standardmäßig integrierte Object-Prototyp-Objekt, wie in 15.2.4.
beschriebenDas Ergebnis sei das Ergebnis des Aufrufs der internen Eigenschaft [[Call]] von F, der Bereitstellung von obj als diesem Wert und der Bereitstellung der Argumentliste, die an [[Construct] übergeben wird. ] als Argumente.
Wenn Typ(Ergebnis) Objekt ist, dann Ergebnis zurückgeben.
Obj zurückgeben.
Sehen Sie sich die Schritte 8 und 9 an:
8) Rufen Sie die FunktionF
auf und weisen Sieresult
ihren Rückgabewert zu; > wird ausgeführt, wird an (d. h.F
selbst),[[Construct]]
internF
zeigt aufF
; 9) Wennthis
vom Typobj
ist, geben Sie ;result
Object
Dies erklärt auch, dass der Konstruktor, wenn er den Objekttyp explizit zurückgibt, dieses Objekt direkt zurückgibt, anstatt das ursprünglich erstellte Objekt zurückzugeben.result
Schauen Sie sich abschließend Schritt 10 an: 10) Wenn
keinen Objekttyp zurückgibt (Schritt 9 ist nicht wahr), geben Sie das erstellte Objektzurück.
F
Wenn der Konstruktor den Objekttyp nicht explizit zurückgibt (explizit den Basisdatentyp zurückgibt oder ihn nicht direkt zurückgibt), wird das ursprünglich erstellte Objekt zurückgegeben.obj
2.2 Der Fall der PfeilfunktionWas ist, wenn der Konstruktor eine Pfeilfunktion ist?
aufgerufen werden und es wird ein Fehler gemeldet.
HINWEIS: Dabei bezieht sich [[Construct]]
auf den Konstruktor selbst. new
[[Construct]]
3) Der vollständige Prozess der neuen Aufruffunktion
3.1 Chinesische Beschreibung und zugehörige Codeanalyse
1)创建 ECMAScript 原生对象 obj
;
2)给 obj
设置原生对象的内部属性;(和原型属性不同,内部属性表示为 [[PropertyName]]
,两个方括号包裹属性名,并且属性名大写,比如常见 [[Prototype]]
、[[Constructor]]
)
3)设置 obj
的内部属性 [[Class]]
为 Object
;
4)设置 obj
的内部属性 [[Extensible]]
为 true
;
5)将 proto
的值设置为 F
的 prototype
属性值;
6)如果 proto
是对象类型,则设置 obj
的内部属性 [[Prototype]]
值为 proto
;(进行原型链关联,实现继承的关键)
7)如果 proto
是不对象类型,则设置 obj
的内部属性 [[Prototype]]
值为内建构造函数 Object 的 prototype
值;(函数 prototype
属性可以被改写,如果改成非对象类型,obj
的 [[Prototype]]
就指向 Object 的原型对象)
8)9)10)见上节分析。(决定返回什么)
对于第 7 步的情况,见下面代码:
function Foo(name) { this.name = name; } var o1 = new Foo("xiaoming"); console.log(o1.__proto__ === Foo.prototype); // true // 重写构造函数原型属性为非对象类型,实例内部 [[Prototype]] 属性指向 Object 原型对象 // 因为实例是一个对象类型的数据,默认会继承内建对象的原型, // 如果构造函数的原型不满足形成原型链的要求,那就跳过直接和内建对象原型关联 Foo.prototype = 1; var o2 = new Foo("xiaohong"); console.log(o2.__proto__ === Foo.prototype); // false console.log(o2.__proto__ === Object.prototype); // true
若执行 new Foo()
,过程如下:
1)创建新对象 o
;
2)给新对象的内部属性赋值,关键是给[[Prototype]]
属性赋值,构造原型链(如果构造函数的原型是 Object 类型,则指向构造函数的原型;不然指向 Object 对象的原型);
3)执行函数 Foo
,执行过程中内部 this
指向新创建的对象 o
;
4)如果 Foo
内部显式返回对象类型数据,则,返回该数据,执行结束;不然返回新创建的对象 o
。
关于一个数据是否是 Object
类型,可以通过 instanceof
操作符进行判断:如果 x instanceof Object
返回 true
,则 x
为 Object
类型。
由上可知,null instanceof Object
返回 false
,所以 null
不是 Object
类型,尽管typeof null
返回 "Object"。
instanceof
的工作原理是:在表达式 x instanceof Foo
中,如果 Foo
的原型(即 Foo.prototype
)出现在 x
的原型链中,则返回 true
,不然,返回 false
。
因为函数的原型可以被改写,所以会出现在 x
通过 Foo
new 出来之后完全改写 Foo
的原型 x instanceof Foo
返回 false
的情况。因为实例创建之后重写构造函数原型,实例指向的原型已经不是构造函数的新的原型了,见下面代码:
const Foo = function() {}; const o = new Foo(); o instanceof Foo; // true // 重写 Foo 原型 Foo.prototype = {}; o instanceof Foo; // false
以上就是本文的全部内容,希望对大家的学习有所帮助,更多相关内容请关注PHP中文网!
相关推荐:
Das obige ist der detaillierte Inhalt vonEinführung in das Prinzip neuer Aufruffunktionen in JS. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!