Heim Web-Frontend js-Tutorial Detaillierte Einführung in defineProperty und Proxy in ES6 (Codebeispiel)

Detaillierte Einführung in defineProperty und Proxy in ES6 (Codebeispiel)

Nov 12, 2018 pm 04:45 PM
defineproperty ecmascript es6 javascript

Dieser Artikel bietet Ihnen eine detaillierte Einführung (Codebeispiel) zu defineProperty und Proxy. Ich hoffe, dass er für Sie hilfreich ist.

Wir haben mehr oder weniger das Wort „Datenbindung“ gehört. Der Schlüssel zur „Datenbindung“ besteht darin, Änderungen in Daten zu überwachen, aber für ein solches Objekt: var obj = {Wert: 1}, wie Wir wissen, dass sich obj geändert hat?

definePropety

ES5 stellt die Object.defineProperty-Methode bereit, die eine neue Eigenschaft für ein Objekt definieren oder eine vorhandene Eigenschaft eines Objekts ändern und dieses Objekt zurückgeben kann .

Syntax

Object.defineProperty(obj, prop, descriptor)

Parameter

obj: 要在其上定义属性的对象。

prop:  要定义或修改的属性的名称。

descriptor: 将被定义或修改的属性的描述符。
Nach dem Login kopieren

Beispiel :

var obj = {};
Object.defineProperty(obj, "num", {
    value : 1,
    writable : true,
    enumerable : true,
    configurable : true
});
//  对象 obj 拥有属性 num,值为 1
Nach dem Login kopieren

Obwohl wir Eigenschaften und Werte direkt hinzufügen können, können wir mit dieser Methode weitere Konfigurationen vornehmen. Der Attributdeskriptor, der durch den dritten Parameterdeskriptor der Funktion

dargestellt wird, hat zwei Formen: Datendeskriptor und Zugriffsdeskriptor .

Beide haben die folgenden zwei Schlüsselwerte :

konfigurierbar

Nur ​​dann, wenn das konfigurierbare Attribut „Wann“ ist true, der Eigenschaftsdeskriptor kann geändert oder gelöscht werden. Der Standardwert ist falsch.

aufzählbar

Nur ​​wenn die Aufzählung der Eigenschaft wahr ist, kann die Eigenschaft in der Aufzählungseigenschaft des Objekts erscheinen. Der Standardwert ist falsch.

Der Datendeskriptor verfügt außerdem über die folgenden optionalen Schlüsselwerte :

Wert

Der entsprechende Wert zu diesem Attribut. Kann jeder gültige JavaScript-Wert sein (Zahl, Objekt, Funktion usw.). Der Standardwert ist undefiniert.

beschreibbar

Diese Eigenschaft kann vom Zuweisungsoperator genau dann geändert werden, wenn beschreibbar der Eigenschaft wahr ist. Der Standardwert ist falsch.

Der Zugriffsdeskriptor verfügt außerdem über die folgenden optionalen Schlüsselwerte :

get

eins vorgesehen Die Attribut-Getter-Methode. Wenn kein Getter vorhanden ist, ist sie undefiniert. Der Rückgabewert dieser Methode wird als Attributwert verwendet. Der Standardwert ist undefiniert.

set

Eine Methode, die einen Setter für eine Eigenschaft bereitstellt. Wenn kein Setter vorhanden ist, ist er undefiniert. Diese Methode akzeptiert einen eindeutigen Parameter und weist der Eigenschaft den neuen Wert dieses Parameters zu. Der Standardwert ist undefiniert.

Es ist erwähnenswert:

Der Attributdeskriptor muss eine von zwei Formen haben: Datendeskriptor oder Zugriffsdeskriptor, kann nicht beides sein gleichzeitig. Das heißt, Sie können:

Object.defineProperty({}, "num", {
    value: 1,
    writable: true,
    enumerable: true,
    configurable: true
});
Nach dem Login kopieren

oder Sie können:

var value = 1;
Object.defineProperty({}, "num", {
    get : function(){
      return value;
    },
    set : function(newValue){
      value = newValue;
    },
    enumerable : true,
    configurable : true
});
Nach dem Login kopieren

, aber nicht:

// 报错
Object.defineProperty({}, "num", {
    value: 1,
    get: function() {
        return 1;
    }
});
Nach dem Login kopieren

Darüber hinaus sind alle Eigenschaftsdeskriptoren optional, das Deskriptorfeld ist jedoch erforderlich . Wenn Sie nichts konfigurieren, können Sie Folgendes tun:

var obj = Object.defineProperty({}, "num", {});
console.log(obj.num); // undefined
Nach dem Login kopieren

Setter und Getter

Der Grund, warum wir über defineProperty sprechen, ist, dass wir get und verwenden möchten Im Zugriffsdeskriptor festgelegt, werden diese beiden Methoden auch Getter und Setter genannt. Durch Getter und Setter definierte Eigenschaften werden als „Accessor-Eigenschaften“ bezeichnet.

Wenn ein Programm den Wert einer Accessor-Eigenschaft abfragt, ruft JavaScript die Getter-Methode auf. Der Rückgabewert dieser Methode ist der Wert des Attributzugriffsausdrucks. Wenn ein Programm den Wert einer Accessor-Eigenschaft festlegt, ruft JavaScript die Setter-Methode auf und übergibt den Wert auf der rechten Seite des Zuweisungsausdrucks als Parameter an den Setter. In gewissem Sinne ist diese Methode für das „Festlegen“ des Eigenschaftswerts verantwortlich. Der Rückgabewert der Setter-Methode kann ignoriert werden.

Zum Beispiel:

var obj = {}, value = null;
Object.defineProperty(obj, "num", {
    get: function(){
        console.log('执行了 get 操作')
        return value;
    },
    set: function(newValue) {
        console.log('执行了 set 操作')
        value = newValue;
    }
})

obj.value = 1 // 执行了 set 操作

console.log(obj.value); // 执行了 get 操作 // 1
Nach dem Login kopieren

Ist das nicht die Art und Weise, wie wir Datenänderungen überwachen wollen? Fassen wir es noch einmal zusammen:

function Archiver() {
    var value = null;
    // archive n. 档案
    var archive = [];

    Object.defineProperty(this, 'num', {
        get: function() {
            console.log('执行了 get 操作')
            return value;
        },
        set: function(value) {
            console.log('执行了 set 操作')
            value = value;
            archive.push({ val: value });
        }
    });

    this.getArchive = function() { return archive; };
}

var arc = new Archiver();
arc.num; // 执行了 get 操作
arc.num = 11; // 执行了 set 操作
arc.num = 13; // 执行了 set 操作
console.log(arc.getArchive()); // [{ val: 11 }, { val: 13 }]
Nach dem Login kopieren

watch API

Da Datenänderungen überwacht werden können, kann ich mir vorstellen, dass bei Datenänderungen die Rendering-Arbeit automatisch durchgeführt wird. . Beispiel:

Es gibt ein Span-Tag und ein Button-Tag in HTML

<span id="container">1</span>
<button id="button">点击加 1</button>
Nach dem Login kopieren

Wenn auf die Schaltfläche geklickt wird, wird der Wert im Span-Tag um 1 erhöht.

Der traditionelle Ansatz ist:

document.getElementById('button').addEventListener("click", function(){
    var container = document.getElementById("container");
    container.innerHTML = Number(container.innerHTML) + 1;
});
Nach dem Login kopieren

Wenn defineProperty verwendet wird:

var obj = {
    value: 1
}

// 储存 obj.value 的值
var value = 1;

Object.defineProperty(obj, "value", {
    get: function() {
        return value;
    },
    set: function(newValue) {
        value = newValue;
        document.getElementById('container').innerHTML = newValue;
    }
});

document.getElementById('button').addEventListener("click", function() {
    obj.value += 1;
});
Nach dem Login kopieren

Der Code scheint zu wachsen, aber wenn wir den Wert im Span-Tag direkt ändern müssen Ändern Sie einfach den Wert von obj.value.

Bei der aktuellen Schreibweise müssen wir jedoch immer noch eine separate Variable deklarieren, um den Wert von obj.value zu speichern, denn wenn Sie direkt obj.value = newValue in set eingeben, geraten Sie in eine Endlosschleife. Darüber hinaus müssen wir möglicherweise Änderungen in vielen Attributwerten überwachen. Es wäre ermüdend, sie einzeln zu schreiben, also schreiben wir einfach eine Überwachungsfunktion. Die Auswirkung der Verwendung ist wie folgt:

var obj = {
    value: 1
}

watch(obj, "num", function(newvalue){
    document.getElementById('container').innerHTML = newvalue;
})

document.getElementById('button').addEventListener("click", function(){
    obj.value += 1
});
Nach dem Login kopieren

Schreiben wir diese Überwachungsfunktion:

(function(){
    var root = this;
    function watch(obj, name, func){
        var value = obj[name];

        Object.defineProperty(obj, name, {
            get: function() {
                return value;
            },
            set: function(newValue) {
                value = newValue;
                func(value)
            }
        });

        if (value) obj[name] = value
    }

    this.watch = watch;
})()
Nach dem Login kopieren

Jetzt können wir Änderungen in Objektattributwerten überwachen und Rückruffunktionen basierend auf Änderungen in Attributwerten hinzufügen ~

Proxy

Die Verwendung von defineProperty kann nur das Leseverhalten (Get) und das Festlegen (Setzen) von Eigenschaften neu definieren. In ES6 wird Proxy bereitgestellt, sodass Sie es neu definieren können Weitere Verhaltensweisen wie „In“, „Löschen“, „Funktionsaufrufe“ und mehr.

Proxy 这个词的原意是代理,用在这里表示由它来“代理”某些操作,ES6 原生提供 Proxy 构造函数,用来生成 Proxy 实例。我们来看看它的语法:

var proxy = new Proxy(target, handler);
Nach dem Login kopieren

proxy 对象的所有用法,都是上面这种形式,不同的只是handler参数的写法。其中,new Proxy()表示生成一个Proxy实例,target参数表示所要拦截的目标对象,handler参数也是一个对象,用来定制拦截行为。

var proxy = new Proxy({}, {
    get: function(obj, prop) {
        console.log('设置 get 操作')
        return obj[prop];
    },
    set: function(obj, prop, value) {
        console.log('设置 set 操作')
        obj[prop] = value;
    }
});

proxy.time = 35; // 设置 set 操作

console.log(proxy.time); // 设置 get 操作 // 35
Nach dem Login kopieren

除了 get 和 set 之外,proxy 可以拦截多达 13 种操作,比如 has(target, propKey),可以拦截 propKey in proxy 的操作,返回一个布尔值。

// 使用 has 方法隐藏某些属性,不被 in 运算符发现
var handler = {
  has (target, key) {
    if (key[0] === '_') {
      return false;
    }
    return key in target;
  }
};
var target = { _prop: 'foo', prop: 'foo' };
var proxy = new Proxy(target, handler);
console.log('_prop' in proxy); // false
Nach dem Login kopieren

又比如说 apply 方法拦截函数的调用、call 和 apply 操作。

apply 方法可以接受三个参数,分别是目标对象、目标对象的上下文对象(this)和目标对象的参数数组,不过这里我们简单演示一下:

var target = function () { return 'I am the target'; };
var handler = {
  apply: function () {
    return 'I am the proxy';
  }
};

var p = new Proxy(target, handler);

p();
// "I am the proxy"
Nach dem Login kopieren

又比如说 ownKeys 方法可以拦截对象自身属性的读取操作。具体来说,拦截以下操作:

  • Object.getOwnPropertyNames()

  • Object.getOwnPropertySymbols()

  • Object.keys()

下面的例子是拦截第一个字符为下划线的属性名,不让它被 for of 遍历到。

let target = {
  _bar: 'foo',
  _prop: 'bar',
  prop: 'baz'
};

let handler = {
  ownKeys (target) {
    return Reflect.ownKeys(target).filter(key => key[0] !== '_');
  }
};

let proxy = new Proxy(target, handler);
for (let key of Object.keys(proxy)) {
  console.log(target[key]);
}
// "baz"
Nach dem Login kopieren

更多的拦截行为可以查看阮一峰老师的 《ECMAScript 6 入门》

值得注意的是,proxy 的最大问题在于浏览器支持度不够,而且很多效果无法使用 poilyfill 来弥补。

watch API 优化

我们使用 proxy 再来写一下 watch 函数。使用效果如下:

(function() {
    var root = this;

    function watch(target, func) {

        var proxy = new Proxy(target, {
            get: function(target, prop) {
                return target[prop];
            },
            set: function(target, prop, value) {
                target[prop] = value;
                func(prop, value);
            }
        });

        if(target[name]) proxy[name] = value;
        return proxy;
    }

    this.watch = watch;
})()

var obj = {
    value: 1
}

var newObj = watch(obj, function(key, newvalue) {
    if (key == 'value') document.getElementById('container').innerHTML = newvalue;
})

document.getElementById('button').addEventListener("click", function() {
    newObj.value += 1
});
Nach dem Login kopieren

我们也可以发现,使用 defineProperty 和 proxy 的区别,当使用 defineProperty,我们修改原来的 obj 对象就可以触发拦截,而使用 proxy,就必须修改代理对象,即 Proxy 的实例才可以触发拦截。

Das obige ist der detaillierte Inhalt vonDetaillierte Einführung in defineProperty und Proxy in ES6 (Codebeispiel). Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Erklärung dieser Website
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

Heiße KI -Werkzeuge

Undresser.AI Undress

Undresser.AI Undress

KI-gestützte App zum Erstellen realistischer Aktfotos

AI Clothes Remover

AI Clothes Remover

Online-KI-Tool zum Entfernen von Kleidung aus Fotos.

Undress AI Tool

Undress AI Tool

Ausziehbilder kostenlos

Clothoff.io

Clothoff.io

KI-Kleiderentferner

AI Hentai Generator

AI Hentai Generator

Erstellen Sie kostenlos Ai Hentai.

Heißer Artikel

R.E.P.O. Energiekristalle erklärten und was sie tun (gelber Kristall)
2 Wochen vor By 尊渡假赌尊渡假赌尊渡假赌
Repo: Wie man Teamkollegen wiederbelebt
1 Monate vor By 尊渡假赌尊渡假赌尊渡假赌
Hello Kitty Island Abenteuer: Wie man riesige Samen bekommt
4 Wochen vor By 尊渡假赌尊渡假赌尊渡假赌

Heiße Werkzeuge

Notepad++7.3.1

Notepad++7.3.1

Einfach zu bedienender und kostenloser Code-Editor

SublimeText3 chinesische Version

SublimeText3 chinesische Version

Chinesische Version, sehr einfach zu bedienen

Senden Sie Studio 13.0.1

Senden Sie Studio 13.0.1

Leistungsstarke integrierte PHP-Entwicklungsumgebung

Dreamweaver CS6

Dreamweaver CS6

Visuelle Webentwicklungstools

SublimeText3 Mac-Version

SublimeText3 Mac-Version

Codebearbeitungssoftware auf Gottesniveau (SublimeText3)

So implementieren Sie ein Online-Spracherkennungssystem mit WebSocket und JavaScript So implementieren Sie ein Online-Spracherkennungssystem mit WebSocket und JavaScript Dec 17, 2023 pm 02:54 PM

So implementieren Sie mit WebSocket und JavaScript ein Online-Spracherkennungssystem. Einführung: Mit der kontinuierlichen Weiterentwicklung der Technologie ist die Spracherkennungstechnologie zu einem wichtigen Bestandteil des Bereichs der künstlichen Intelligenz geworden. Das auf WebSocket und JavaScript basierende Online-Spracherkennungssystem zeichnet sich durch geringe Latenz, Echtzeit und plattformübergreifende Eigenschaften aus und hat sich zu einer weit verbreiteten Lösung entwickelt. In diesem Artikel wird erläutert, wie Sie mit WebSocket und JavaScript ein Online-Spracherkennungssystem implementieren.

WebSocket und JavaScript: Schlüsseltechnologien zur Implementierung von Echtzeitüberwachungssystemen WebSocket und JavaScript: Schlüsseltechnologien zur Implementierung von Echtzeitüberwachungssystemen Dec 17, 2023 pm 05:30 PM

WebSocket und JavaScript: Schlüsseltechnologien zur Realisierung von Echtzeit-Überwachungssystemen Einführung: Mit der rasanten Entwicklung der Internet-Technologie wurden Echtzeit-Überwachungssysteme in verschiedenen Bereichen weit verbreitet eingesetzt. Eine der Schlüsseltechnologien zur Erzielung einer Echtzeitüberwachung ist die Kombination von WebSocket und JavaScript. In diesem Artikel wird die Anwendung von WebSocket und JavaScript in Echtzeitüberwachungssystemen vorgestellt, Codebeispiele gegeben und deren Implementierungsprinzipien ausführlich erläutert. 1. WebSocket-Technologie

So implementieren Sie ein Online-Reservierungssystem mit WebSocket und JavaScript So implementieren Sie ein Online-Reservierungssystem mit WebSocket und JavaScript Dec 17, 2023 am 09:39 AM

So implementieren Sie ein Online-Reservierungssystem mit WebSocket und JavaScript. Im heutigen digitalen Zeitalter müssen immer mehr Unternehmen und Dienste Online-Reservierungsfunktionen bereitstellen. Es ist von entscheidender Bedeutung, ein effizientes Online-Reservierungssystem in Echtzeit zu implementieren. In diesem Artikel wird erläutert, wie Sie mit WebSocket und JavaScript ein Online-Reservierungssystem implementieren, und es werden spezifische Codebeispiele bereitgestellt. 1. Was ist WebSocket? WebSocket ist eine Vollduplex-Methode für eine einzelne TCP-Verbindung.

Verwendung von JavaScript und WebSocket zur Implementierung eines Echtzeit-Online-Bestellsystems Verwendung von JavaScript und WebSocket zur Implementierung eines Echtzeit-Online-Bestellsystems Dec 17, 2023 pm 12:09 PM

Einführung in die Verwendung von JavaScript und WebSocket zur Implementierung eines Online-Bestellsystems in Echtzeit: Mit der Popularität des Internets und dem Fortschritt der Technologie haben immer mehr Restaurants damit begonnen, Online-Bestelldienste anzubieten. Um ein Echtzeit-Online-Bestellsystem zu implementieren, können wir JavaScript und WebSocket-Technologie verwenden. WebSocket ist ein Vollduplex-Kommunikationsprotokoll, das auf dem TCP-Protokoll basiert und eine bidirektionale Kommunikation zwischen Client und Server in Echtzeit realisieren kann. Im Echtzeit-Online-Bestellsystem, wenn der Benutzer Gerichte auswählt und eine Bestellung aufgibt

JavaScript und WebSocket: Aufbau eines effizienten Echtzeit-Wettervorhersagesystems JavaScript und WebSocket: Aufbau eines effizienten Echtzeit-Wettervorhersagesystems Dec 17, 2023 pm 05:13 PM

JavaScript und WebSocket: Aufbau eines effizienten Echtzeit-Wettervorhersagesystems Einführung: Heutzutage ist die Genauigkeit von Wettervorhersagen für das tägliche Leben und die Entscheidungsfindung von großer Bedeutung. Mit der Weiterentwicklung der Technologie können wir genauere und zuverlässigere Wettervorhersagen liefern, indem wir Wetterdaten in Echtzeit erhalten. In diesem Artikel erfahren Sie, wie Sie mit JavaScript und WebSocket-Technologie ein effizientes Echtzeit-Wettervorhersagesystem aufbauen. In diesem Artikel wird der Implementierungsprozess anhand spezifischer Codebeispiele demonstriert. Wir

Einfaches JavaScript-Tutorial: So erhalten Sie den HTTP-Statuscode Einfaches JavaScript-Tutorial: So erhalten Sie den HTTP-Statuscode Jan 05, 2024 pm 06:08 PM

JavaScript-Tutorial: So erhalten Sie HTTP-Statuscode. Es sind spezifische Codebeispiele erforderlich. Vorwort: Bei der Webentwicklung ist häufig die Dateninteraktion mit dem Server erforderlich. Bei der Kommunikation mit dem Server müssen wir häufig den zurückgegebenen HTTP-Statuscode abrufen, um festzustellen, ob der Vorgang erfolgreich ist, und die entsprechende Verarbeitung basierend auf verschiedenen Statuscodes durchführen. In diesem Artikel erfahren Sie, wie Sie mit JavaScript HTTP-Statuscodes abrufen und einige praktische Codebeispiele bereitstellen. Verwenden von XMLHttpRequest

So erhalten Sie auf einfache Weise HTTP-Statuscode in JavaScript So erhalten Sie auf einfache Weise HTTP-Statuscode in JavaScript Jan 05, 2024 pm 01:37 PM

Einführung in die Methode zum Abrufen des HTTP-Statuscodes in JavaScript: Bei der Front-End-Entwicklung müssen wir uns häufig mit der Interaktion mit der Back-End-Schnittstelle befassen, und der HTTP-Statuscode ist ein sehr wichtiger Teil davon. Das Verstehen und Abrufen von HTTP-Statuscodes hilft uns, die von der Schnittstelle zurückgegebenen Daten besser zu verarbeiten. In diesem Artikel wird erläutert, wie Sie mithilfe von JavaScript HTTP-Statuscodes erhalten, und es werden spezifische Codebeispiele bereitgestellt. 1. Was ist ein HTTP-Statuscode? HTTP-Statuscode bedeutet, dass der Dienst den Dienst anfordert, wenn er eine Anfrage an den Server initiiert

So verwenden Sie insertBefore in Javascript So verwenden Sie insertBefore in Javascript Nov 24, 2023 am 11:56 AM

Verwendung: In JavaScript wird die Methode insertBefore() verwendet, um einen neuen Knoten in den DOM-Baum einzufügen. Diese Methode erfordert zwei Parameter: den neuen Knoten, der eingefügt werden soll, und den Referenzknoten (d. h. den Knoten, an dem der neue Knoten eingefügt wird).

See all articles