Heim >Web-Frontend >js-Tutorial >Detaillierte Einführung in die Erstellung von Objekten in JavaScript

Detaillierte Einführung in die Erstellung von Objekten in JavaScript

零下一度
零下一度Original
2017-06-28 13:43:131015Durchsuche

In diesem Artikel werden hauptsächlich die relevanten Informationen zu mit JavaScript erstellten Objekten ausführlich vorgestellt. Interessierte Freunde können auf

JavaScript wird für jedes erstellte Objekt verwiesen werden ein Prototyp, der auf sein Prototypobjekt zeigt.

Wenn wir obj.xxx verwenden, um auf die Eigenschaften eines Objekts zuzugreifen, sucht die JavaScript-Engine zunächst nach der Eigenschaft des aktuellen Objekts. Wenn sie nicht gefunden wird, sucht sie nach ihrem Prototypobjekt Es wird noch nicht gefunden. Es geht bis zum Object.prototype-Objekt zurück. Wenn es schließlich noch nicht gefunden wird, kann es nur undefiniert zurückgegeben werden.
Erstellen Sie beispielsweise ein Array-Objekt:

var arr = [1, 2, 3];

Seine Prototypenkette lautet:

arr ----> - ---> Object.prototype ----> null

Array.prototype definiert indexOf(), shift() und andere Methoden, sodass Sie alle Array-Objekte verwenden können Rufen Sie diese Methoden direkt auf.
Wenn wir eine Funktion erstellen:

function foo() {
  return 0;
}

Die Funktion ist auch ein Objekt und ihre Prototypkette ist:

foo ----> - ---> Object.prototype ----> null

Da Function.prototype Methoden wie apply() definiert, können alle Funktionen die apply()-Methode aufrufen.

Man kann leicht annehmen, dass der Zugriff auf die Eigenschaften eines Objekts langsamer wird, wenn die Prototypenkette lang ist, da das Nachschlagen mehr Zeit in Anspruch nimmt. Achten Sie also darauf, keine Prototypenkette zu erstellen zu groß lang.

Konstruktor

Zusätzlich zur direkten Verwendung von { ... } zum Erstellen eines Objekts kann JavaScript auch eine Konstruktormethode zum Erstellen von Objekten verwenden. Seine Verwendung besteht darin, zunächst einen Konstruktor zu definieren:

function Student(name) {
  this.name = name;
  this.hello = function () {
    alert('Hello, ' + this.name + '!');
  }
}

Sie fragen sich vielleicht, hey, ist das nicht eine gewöhnliche Funktion?

Dies ist in der Tat eine gewöhnliche Funktion, aber in JavaScript können Sie das Schlüsselwort new verwenden, um diese Funktion aufzurufen und ein Objekt zurückzugeben:

var xiaoming = new Student('小明');
xiaoming.name; // '小明'
xiaoming.hello(); // Hello, 小明!

Beachten Sie dies, wenn Sie dies nicht tun write new, das ist eine normale Funktion, sie gibt undefiniert zurück. Wenn jedoch new geschrieben wird, wird es zu einem Konstruktor, der an ihn gebunden ist und auf das neu erstellte Objekt zeigt und dieses standardmäßig zurückgibt, d. h., es besteht keine Notwendigkeit, am Ende etwas zurückzugeben.

Die Prototypenkette des neu erstellten Xiaoming ist:

xiaoming ----> Object.prototype - ---> null

Mit anderen Worten, der Prototyp von Xiaoming verweist auf den Prototyp der Funktion Student. Wenn Sie Xiaohong und Xiaojun erstellen, sind die Prototypen dieser Objekte dieselben wie Xiaoming:
xiaoming ↘
xiaohong -→ Student.prototype ----> Object.prototype ---- > null
xiaojun ↗

Das mit new Student() erstellte Objekt erhält auch ein Konstruktorattribut vom Prototyp, das auf die Funktion Student selbst verweist:

xiaoming.constructor === Student.prototype.constructor; // true
Student.prototype.constructor === Student; // true

Object.getPrototypeOf(xiaoming) === Student.prototype; // true

xiaoming instanceof Student; // true

Ist dir schwindelig? Ein Diagramm zur Darstellung dieser chaotischen Beziehungen ist:

Der rote Pfeil ist die Prototypenkette. Beachten Sie, dass das Objekt, auf das Student.prototype zeigt, das Prototypobjekt von Xiaoming und Xiaohong ist. Dieses Prototypobjekt selbst verfügt über einen Attributkonstruktor, der auf die Student-Funktion selbst verweist.
Außerdem verfügt die Funktion Student zufällig über ein Attributprototyp, das auf die Prototypobjekte von Xiaoming und Xiaohong verweist. Xiaoming- und Xiaohongobjekte verfügen jedoch nicht über das Prototypattribut, können aber mit der nicht standardmäßigen Verwendung angezeigt werden von Proto.
Jetzt glauben wir, dass Objekte wie Xiaoming und Xiaohong von Student „erben“.
Aber es gibt immer noch ein kleines Problem, bitte achten Sie darauf:

xiaoming.name; // '小明'
xiaohong.name; // '小红'
xiaoming.hello; // function: Student.hello()
xiaohong.hello; // function: Student.hello()
xiaoming.hello === xiaohong.hello; // false

Xiaoming und Xiaohong haben unterschiedliche Namen, was richtig ist, sonst können wir nicht unterscheiden, wer wer ist.
Die jeweiligen Hallos von Xiaoming und Xiaohong sind eine Funktion, aber es sind zwei verschiedene Funktionen, obwohl die Funktionsnamen und Codes gleich sind!
Wenn wir viele Objekte über new Student () erstellen, müssen die Hallo-Funktionen dieser Objekte tatsächlich nur dieselbe Funktion teilen, was viel Speicher sparen kann.

Damit die erstellten Objekte eine gemeinsame Hallo-Funktion haben, müssen wir gemäß dem Prinzip der Objektattributsuche nur die Hallo-Funktion in den gemeinsamen Prototyp von Xiaoming- und Xiaohong-Objekten verschieben, nämlich den Student-Prototyp :

Ändern Sie den Code wie folgt:

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

Student.prototype.hello = function () {
  alert('Hello, ' + this.name + '!');
};

So einfach ist es, mit new prototypbasierte JavaScript-Objekte zu erstellen!

Was soll ich tun, wenn ich vergesse, Neues zu schreiben?

如果一个函数被定义为用于创建对象的构造函数,但是调用时忘记了写new怎么办?
在strict模式下,this.name = name将报错,因为this绑定为undefined,在非strict模式下,this.name = name不报错,因为this绑定为window,于是无意间创建了全局变量name,并且返回undefined,这个结果更糟糕。
所以,调用构造函数千万不要忘记写new。为了区分普通函数和构造函数,按照约定,构造函数首字母应当大写,而普通函数首字母应当小写,这样,一些语法检查工具如jslint将可以帮你检测到漏写的new。
最后,我们还可以编写一个createStudent()函数,在内部封装所有的new操作。一个常用的编程模式像这样:


function Student(props) {
  this.name = props.name || '匿名'; // 默认值为'匿名'
  this.grade = props.grade || 1; // 默认值为1
}

Student.prototype.hello = function () {
  alert('Hello, ' + this.name + '!');
};

function createStudent(props) {
  return new Student(props || {})
}

这个createStudent()函数有几个巨大的优点:一是不需要new来调用,二是参数非常灵活,可以不传,也可以这么传:


var xiaoming = createStudent({
  name: '小明'
});

xiaoming.grade; // 1

如果创建的对象有很多属性,我们只需要传递需要的某些属性,剩下的属性可以用默认值。由于参数是一个Object,我们无需记忆参数的顺序。如果恰好从JSON拿到了一个对象,就可以直接创建出xiaoming。

练习

请利用构造函数定义Cat,并让所有的Cat对象有一个name属性,并共享一个方法say(),返回字符串'Hello, xxx!':

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

Das obige ist der detaillierte Inhalt vonDetaillierte Einführung in die Erstellung von Objekten in JavaScript. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn