検索
ホームページウェブフロントエンドjsチュートリアルES6 の新機能: JavaScript の Reflect オブジェクト コードの詳細な説明

Reflect の概要:

Reflect オブジェクトは私のノード (v4.4.3) には実装されておらず、Chrome の新しいバージョンでもサポートされていません。また、ff はプロキシとリフレクトをサポートしています。ノードが Reflect をサポートするようにするには、harmonie-reflect をインストールします。

Reflect を使用したい場合は、Reflect.method() を通じて直接呼び出すことができます。 Proxy のネイティブ Object メソッドのほとんどがすでに再実装されています。

Reflect を使用する理由

Reflect を使用する必要がある理由をいくつか示します。翻訳アドレス: Reflect、大まかに翻訳すると:

1: より便利な戻り値: Reflect には、ES5 の Object メソッドと同じメソッドがいくつかあります。例: Reflect.getOwnPropertyDescriptor および Reflect.defineProperty ただし、Object.defineProperty(obj, name, desc) は正常に実行された場合は obj を返し、他の理由で発生したエラーはオブジェクトを表すために false または true のみを返します。プロパティが設定されているかどうかに関係なく、次のコードをリファクタリングできます:

try {
  Object.defineProperty(obj, name, desc);
  // property defined successfully
} catch (e) {
  // possible failure (and might accidentally catch the wrong exception)
}

次のようにリファクタリング:

if (Reflect.defineProperty(obj, name, desc)) {
  // success
} else {
  // failure
}

Relect.set、Reflect.deleteProperty、Reflect.preventExtensions、Reflect.setPrototypeOf などの他のメソッドはすべてリファクタリングできます。

2: 関数の操作。obj に定義があるか属性名を継承しているかを判断したい場合、ES5 では次のように判断できます: name in obj または属性を削除します: delete obj[name]。使いやすく、非常に短く、非常にシンプルな Clear ですが、使用する場合はクラスにカプセル化する必要があります

Reflect を使用すると、Reflect.has(obj, name) のようにカプセル化できます。 Reflect.deleteProperty(obj, name);

3: より信頼性の高い関数実行方法: ES では、関数 f を実行し、それにパラメーター引数のセットを渡す必要がある場合、これをバインドする必要があります。次のように:

f.apply(obj, args)

ただし、f の apply は user として再定義される可能性があります。私自身が適用したため、次のように記述する方が確実です:

Function.prototype.apply.call(f, obj, args)

上記のコードは長すぎて、Reflect では理解するのが困難です。より短く、より簡潔で明確にすることができます:

Reflect.apply(f, obj, args)

4: コンストラクター形式の変数パラメーター: ES5 では、次のように記述できる拡張シンボルを使用して、不定の長さのパラメーターを使用してコンストラクターをインスタンス化したいと考えてください。 :

var obj = new F(...args)

しかし、ES5 では拡張文字はサポートされていないため、異なるパラメーターを渡すには F.apply または F.call しか使用できません。残念ながら、F はコンストラクターであり、これはチートですが、Reflect を使用するとそれが可能になります。 ES5 では次のように記述します:

var obj = Reflect.construct(F, args)

5: アクセサーまたはリーダーの制御: ES5 では、要素のプロパティを読み取るか、プロパティを設定したい場合は、これを行う必要があります:

var name = ... // get property name as a string
obj[name] // generic property lookup
obj[name] = value // generic property update

The Reflect.getと Reflect.set メソッドを使用すると同じことを行うことができ、追加のパラメーター レシーバーを使用すると、オブジェクトのセッターの上位コンテキストと下位コンテキストを設定し、これをゲッターできるようになります:

var name = ... // get property name as a string
Reflect.get(obj, name, wrapper) // if obj[name] is an accessor, it gets run with `this === wrapper`
Reflect.set(obj, name, value, wrapper)

アクセサーは独自のメソッドを使用したくない、しかしこれをラッパーにリダイレクトしたい:

var obj = {
    set foo(value) { return this.bar(); },
    bar: function() {
        alert(1);
    }
};
var wrapper = {
    bar : function() {
        console.log("wrapper");
    }
}
Reflect.set(obj, "foo", "value", wrapper);

6: __proto__ への直接アクセスを避ける: ES5 はオブジェクトのプロトタイプにアクセスするための Object.getPrototypeOf(obj) を提供します。ES6 は Reflect.getPrototypeOf(obj) と Reflect.setPrototypeOf(obj, newProto) も提供します。これは、オブジェクトのプロトタイプにアクセスして設定する新しいメソッドです: apply

Reflect.apply の使用は、実際には ES5 の Function.prototype.apply() の代用です。 Reflect.apply を実行します

最初のパラメータは次のとおりです: 実行する必要がある関数です。

2 番目のパラメータは次のとおりです: 関数を実行するために使用する必要があるコンテキストです。

3 番目のパラメータは次のとおりです: 配列または擬似です。 -array、関数を実行するためのパラメータとして使用されます。

<script>
let fn = function() {
    this.attr = [0,1,2,3];
};
let obj = {};
Reflect.apply(fn, obj, [])
console.log(obj);  
</script>


Reflect.apply のデモ:

<script>
Reflect.apply(Math.floor, undefined, [1.75]); // 输出:1;
Reflect.apply(String.fromCharCode, undefined, [104, 101, 108, 108, 111]); // 输出:"hello"
Reflect.apply(RegExp.prototype.exec, /ab/, ["confabulation"]).index; //输出: 4
Reflect.apply("".charAt, "ponies", [3]); // 输出:"i"
</script>
Reflect はプロキシと併用できます。 共同使用:

{
    var  Fn = function(){
    };
    Fn.prototype.run = function() {
        console.log( "runs out" );
    };
    var ProxyFn  = new Proxy(Fn, {
        construct (target ,arugments) {
            console.log("proxy constructor");
            var obj = new target(...arugments);
            //Reflect.apply的使用方法;
            Reflect.apply(target.prototype.run, obj, arugments);
            return obj;
        }
    });
    new ProxyFn ();  //会先输出: "proxy constructor" ; 再输出: runs out
}
Reflect の使用法。 construct():

Reflect.constructは実際にはパラメータを渡す形で実装されていますが、実行方法は異なりますが、実際にはconstructの最初のパラメータがコンストラクタです。 、2 番目のパラメーターはパラメーターで構成される配列または疑似配列です。基本的な使用方法は次のとおりです。

var Fn = function(arg) {
    this.args = [arg]
};
console.log( new Fn(1), Reflect.construct(Fn,[1]) ); // 输出是一样的

var d = Reflect.construct(Date, [1776, 6, 4]);
d instanceof Date; // true
d.getFullYear(); // 1776
//所以Reflect.consturct和new 构

したがって、Reflect.consturct は、少なくともこれまでのところ、新しいコンストラクターと同じです...

Reflect を与えることができます。 .construct は 3 番目のパラメーターを渡し、3 番目のパラメーターはスーパー クラスです

<script>
function someConstructor() {}
var result = Reflect.construct(Array, [], someConstructor);
Reflect.getPrototypeOf(result); // someConstructor.prototype
Array.isArray(result); // true
//or
var Fn = function() {
    this.attr = [1];
};
var Person = function() {
};
Person.prototype.run = function() {
};
console.log( Reflect.construct(Fn, [], Person) );
</script>

したがって、これを使用して特別な配列を実装し、その配列を継承することもできます。独自のメソッド;

var Fn = function() {
    Array.apply(this, arguments);
    this.shot = ()=> {
        console.log("heheda");
    };
};
var arr = Reflect.construct(Fn, [])

Reflect.defineProperty の使用法;

Reflect.defineProperty は、直接代入によってオブジェクトに属性と属性値を追加すると、追加が失敗した場合はオブジェクト全体を返します。間違ってスローされました;

var obj = {};
obj.x = 10;
console.log(obj.x) //输出:10;
値を追加するには Reflect.defineProperty を使用してください;

<script>
var obj = {};
if( Reflect.defineProperty(obj, "x", {value : 7 }) ) {
    console.log("added success");
}else{
    console.log("添加失败");
};
</script>

如果我们执行preventExtensions, 通过Object.defindProperty定义新属性报错了, 但是通过Reflect.defineProperty没有报错, 返回了一个false的值:

var obj = {};
Object.preventExtensions(obj);
Object.defineProperty(obj, "x" , {
    value: 101,
    writable: false,
    enumerable: false,
    configurable: false
});// 直接抛错了;
console.log( Reflect.defineProperty(obj, "x", {value:101}) ) //返回false:

如果通过直接赋值的方式, 无论是否正确赋值, 都返回设置的值, 除非我们手动确认对象的属性值是否设置成功;

<script>
var obj = {};
Object.preventExtensions(obj);
console.log( obj.aa = 1 ); //输出:1;
console.log(obj.aa) //输出:undefined;
</script>

Reflect.deleteProperty的使用:

Reflect.deleteProperty和Reflect.defineProperty的使用方法差不多, Reflect.deleteProperty和 delete obj.xx的操作结果是一样, 区别是使用形式不同:一个是操作符,一个是函数调用;

Reflect.deleteProperty(Object.freeze({foo: 1}), "foo"); // false
delete Object.freeze({foo: 1}).foo; //输出:false;

Reflect.get()方法的使用

这个方法的有两个必须的参数: 第一个为obj目标对象, 第二个为属性名对象, 第三个是可选的,是作为读取器的上下文(this);

var obj = {};
obj.foo = 1;
console.log( obj.foo ); //输出:1;
console.log( Reflect.get(obj, "foo") ) //输出:1;

如果Reflect.get有第三个参数的话, 第三个参数会作为读取器的上下文:

var Reflect = require(&#39;harmony-reflect&#39;);

var obj = {
    "foo" : 1,
    get bar() {
        return this.foo;
    }
};
var foo = {};
foo.foo = "heheda";
console.log(Reflect.get(obj, "bar", foo));

Reflect.getOwnPropertyDescritptor()方法的使用:

通过Reflect.getOwnPropertyDescritptor获取属性描述:

Reflect.getOwnPropertyDescriptor({x: "hello"}, "x");
//也可以这样获取:
Object.getOwnPropertyDescriptor({x:"1"},"x");
//这两个的区别是一个会包装对象, 一个不会:
Reflect.getOwnPropertyDescriptor("hello",0); //抛出异常
Object.getOwnPropertyDescriptor("hello",0); //输出: {value: "h", writable: false, enumerable: true, configurable: false}

Reflect.getPrototypeOf()方法的使用:

Reflect.getPrototypeOf和Object.getPrototypeOf是一样的, 他们都是返回一个对象的原型

Reflect.getPrototypeOf({}); // 输出:Object.prototype
Reflect.getPrototypeOf(Object.prototype); // 输出:null
Reflect.getPrototypeOf(Object.create(null)); // 输出: null

Reflect.has的使用

Reflect.has这个方法有点像操作符:in , 比如这样: xx in obj;

<script>
Reflect.has({x:0}, "x") //输出: true;
Reflect.has({y:0}, "y") //输出:true
; var obj = {x:0}; console.log( "x" in obj); 
var proxy = new Proxy(obj, { has : function(target, args) { console.log("执行has方法"); 
return Reflect.has(target,...args); } }); 
console.log( "x" in proxy); //输出:true; console.log(Reflect.has(proxy, "x")) //输出:true; </script>


这个demo的obj相当于变成了一个方法了, 没他什么用 , 只是利用了他的has方法:

obj = new Proxy({}, {
    has(t, k) { return k.startsWith("door"); }
});
Reflect.has(obj, "doorbell"); // true
Reflect.has(obj, "dormitory"); // false

Reflect.isExtensible()的使用

// 现在这个元素是可以扩展的;
var empty = {};
Reflect.isExtensible(empty); // === true

// 使用preventExtensions方法, 让这个对象无法扩展新属性;
Reflect.preventExtensions(empty);
Reflect.isExtensible(empty); // === false

// 这个对象无法扩展新属性, 可写的属性依然可以改动
var sealed = Object.seal({});
Reflect.isExtensible(sealed); // === false

// 这个对象完全被冻结了
var frozen = Object.freeze({});
Reflect.isExtensible(frozen); // === false

Reflect.isExtensible和Object.isExtensible的区别是, 如果参数不对,一个会抛错, 另一个只是返回true或者false:

Reflect.isExtensible(1);
// 抛错了: 1 is not an object
Object.isExtensible(1);
// 返回false;

Reflect.ownKeys()方法的使用:

Reflect.ownKeys, Object可没有ownKeys方法, Reflect.ownKeysz他的作用是返回对象的keys;

console.log(Reflect.ownKeys({"a":0,"b":1,"c":2,"d":3})); //输出 :["a", "b", "c", "d"]
console.log(Reflect.ownKeys([])); // ["length"]
var sym = Symbol.for("comet");
var sym2 = Symbol.for("meteor");
var obj = {[sym]: 0, "str": 0, "773": 0, "0": 0,
    [sym2]: 0, "-1": 0, "8": 0, "second str": 0};
Reflect.ownKeys(obj); //输出:/ [ "0", "8", "773", "str", "-1", "second str", Symbol(comet), Symbol(meteor) ]

Reflect.ownKeys的排序是根据: 先显示数字, 数字根据大小排序,然后是 字符串根据插入的顺序排序, 最后是symbol类型的key也根据插入插入顺序排序;

出现这中排序是因为,你给一个对象属性赋值时候, 对象的key的排序规则就是先数字, 在字符串, 最后是symbol类型的数据;

Reflect.preventExtensions()的使用方法:

Object也有preventExtensions方法, 和Reflect.preventExtensions()有一点区别, 如果Reflect.preventExtensions参数不是对象会抛错;

var empty = {};
Reflect.isExtensible(empty); // === true

// 执行preventExtensions后的对象可以修改;
Reflect.preventExtensions(empty);
Reflect.isExtensible(empty); // === false

Reflect.preventExtensions(1);
// TypeError: 1 is not an object
Object.preventExtensions(1);
//不会抛错, 会返回:1

Reflect.set()

Reflect.set方法和get是差不多的;

var obj = {};
Reflect.set(obj, "prop", "value"); // 输出:true
console.log( obj.prop ); // 输出:"value"

var arr = ["duck", "duck", "duck"];
Reflect.set(arr, 2, "goose"); // true
console.log( arr[2] ); // "goose"

Reflect.set(arr, "length", 1); // true
console.log( arr );// ["duck"];

Reflect.set(obj)相当于 Reflect.set(obj, undefined, undefined);

var obj = {};
Reflect.set(obj); // 输出:true
//以上的代码相当于 Reflect.set(obj, undefined, undefined);
Reflect.getOwnPropertyDescriptor(obj, "undefined");
// { value: undefined, writable: true, enumerable: true, configurable: true }

Reflect.set也可以有第四个参数, 这个参数会作为stter的this;

var obj = {
    value : 10,
    set key( value ) {
        console.log("setter");
        this.value =  value;
    },
    get key() {
        return this.value;
    }
};
Reflect.set(obj,"key","heheda", obj);
console.log(obj);

Reflect.setPrototypeOf()

Reflect.setPrototypeOf()方法和Object.setPrototypeOf差不多一样样的, 会给对象设置原型, 就是更改对象的__proto__属性了…;

Reflect.setPrototypeOf({}, Object.prototype); // 输出true

// 给该对象数组[[Prototype]] 为null.
Reflect.setPrototypeOf({}, null); // true
// 此时的obj.__proto__为undefine

//把对象冻结以后重新设置[[prototype]]
Reflect.setPrototypeOf(Object.freeze({}), null); // false

// 如果原型链循环依赖的话就会返回false.
var target = {};
var proto = Object.create(target);
Reflect.setPrototypeOf(target, proto); // false

 以上就是ES6新特性:JavaScript中的Reflect对象代码详解的内容,更多相关内容请关注PHP中文网(www.php.cn)!



声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
es6怎么判断是否为数组es6怎么判断是否为数组Apr 25, 2022 pm 06:43 PM

在es6中,可以利用“Array.isArray()”方法判断对象是否为数组,若判断的对象是数组,返回的结果是true,若判断对象不是数组,返回的结果是false,语法为“Array.isArray(需要检测的js对象)”。

es6中遍历跟迭代的区别是什么es6中遍历跟迭代的区别是什么Apr 26, 2022 pm 02:57 PM

es6中遍历跟迭代的区别是:遍历强调的是要把整个数据依次全部取出来,是访问数据结构的所有元素;而迭代虽然也是依次取出数据,但是并不保证取多少,也不保证把所有的数据取完,是遍历的一种形式。

es6中怎么判断两个对象是否相等es6中怎么判断两个对象是否相等Apr 19, 2022 pm 03:34 PM

在es6中,可用Object对象的is()方法来判断两个对象是否相等,该方法检测两个变量的值是否为同一个值,判断两个对象的引用地址是否一致,语法“Object.is(对象1,对象2)”;该方法会返回布尔值,若返回true则表示两个对象相等。

es6怎么将数字转为字符串es6怎么将数字转为字符串Apr 19, 2022 pm 06:38 PM

转换方法:1、利用“+”给数字拼接一个空字符,语法“数字+""”;2、使用String(),可把对象的值转换为字符串,语法“String(数字对象)”;3、用toString(),可返回数字的字符串表示,语法“数字.toString()”。

sort排序是es6中的吗sort排序是es6中的吗Apr 25, 2022 pm 03:30 PM

sort排序是es6中的;sort排序是es6中用于对数组的元素进行排序的方法,该方法默认不传参,按照字符编码顺序进行排序,排序顺序可以是字母或数字,并按升序或降序,语法为“array.sort(callback(a,b))”。

es6怎么改变数组数据es6怎么改变数组数据Apr 26, 2022 am 10:08 AM

改变方法:1、利用splice()方法修改,该方法可以直接修改原数组的内容,语法为“数组.splice(开始位置,修改个数,修改后的值)”;2、利用下标访问数组元素,并重新赋值来修改数组数据,语法为“数组[下标值]=修改后的值;”。

es6中assign的用法是什么es6中assign的用法是什么May 05, 2022 pm 02:25 PM

在es6中,assign用于对象的合并,可以将源对象的所有可枚举属性复制到目标对象;若目标对象与源对象有同名属性,或多个源对象有同名属性,则后面的属性会覆盖前面的属性,语法为“Object.assign(...)”

import as在es6中的用法是什么import as在es6中的用法是什么Apr 25, 2022 pm 05:19 PM

在es6中,import as用于将若干export导出的内容组合成一个对象返回;ES6的模块化分为导出与导入两个模块,该方法能够将所有的导出内容包裹到指定对象中,语法为“import * as 对象 from ...”。

See all articles

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

AI Hentai Generator

AI Hentai Generator

AIヘンタイを無料で生成します。

ホットツール

VSCode Windows 64 ビットのダウンロード

VSCode Windows 64 ビットのダウンロード

Microsoft によって発売された無料で強力な IDE エディター

WebStorm Mac版

WebStorm Mac版

便利なJavaScript開発ツール

DVWA

DVWA

Damn Vulnerable Web App (DVWA) は、非常に脆弱な PHP/MySQL Web アプリケーションです。その主な目的は、セキュリティ専門家が法的環境でスキルとツールをテストするのに役立ち、Web 開発者が Web アプリケーションを保護するプロセスをより深く理解できるようにし、教師/生徒が教室環境で Web アプリケーションを教え/学習できるようにすることです。安全。 DVWA の目標は、シンプルでわかりやすいインターフェイスを通じて、さまざまな難易度で最も一般的な Web 脆弱性のいくつかを実践することです。このソフトウェアは、

SecLists

SecLists

SecLists は、セキュリティ テスターの究極の相棒です。これは、セキュリティ評価中に頻繁に使用されるさまざまな種類のリストを 1 か所にまとめたものです。 SecLists は、セキュリティ テスターが必要とする可能性のあるすべてのリストを便利に提供することで、セキュリティ テストをより効率的かつ生産的にするのに役立ちます。リストの種類には、ユーザー名、パスワード、URL、ファジング ペイロード、機密データ パターン、Web シェルなどが含まれます。テスターはこのリポジトリを新しいテスト マシンにプルするだけで、必要なあらゆる種類のリストにアクセスできるようになります。

AtomエディタMac版ダウンロード

AtomエディタMac版ダウンロード

最も人気のあるオープンソースエディター