この記事では主に、js の削除演算子と内部属性インスタンスの詳細な説明を共有します。Configurable を説明する前に、まずインタビューの質問を見てみましょう:
a = 1;console.log( window.a ); // 1console.log( delete window.a ); // trueconsole.log( window.a ); // undefinedvar b = 2;console.log( window.b ); // 2console.log( delete window.b ); // falseconsole.log( window.b ); // 2
上記の質問から、2 つの違いがわかります。 using var で変数を宣言した場合、delete キーワードを使用して変数を削除できますが、再度取得すると値は未定義になります。var で変数を宣言した場合、delete では削除できず、値は未定義になります。もう一度取得してもまだ 2 です。
delete を使用して変数または属性を削除すると、削除が成功した場合は true が返され、そうでない場合は false が返されます。上記の例のように、delete で変数 a を削除できない場合は false が返され、delete で変数 b を正常に削除できた場合は true が返されます。
上記の 2 つの状況に加えて、delete で削除できる一般的に使用される変数と、削除できない変数がさまざまあります。これらの変数を削除するときになぜそのような結果が発生するかについては気にしないでください。ここでは戻り値だけを見てみましょう:
削除配列内の要素の 1 つを削除します:
// 使用for~in是循环不到的,直接忽略到该元素 // 使用for()可以得到该元素,但是值是undefinedvar arr = [1, 2, 3, 4];console.log( arr ); // [1, 2, 3, 4]console.log( delete arr[2] ); // true,删除成功console.log( arr ); // [1, 2, undefined, 4]
関数型変数を削除します:
// chrome 不能删除;火狐可以删除function func(){ } console.log( func );console.log( delete func ); console.log( func );
関数。 length 、長さは取得した仮パラメータの数です:
function func1(a, b){ }console.log( func1.length ); // 2console.log( delete func1.length ); // true,删除成功console.log( func1.length ); // 0
共通変数を削除:
console.log( delete NaN ); // false,删除失败console.log( delete undefined ); // falseconsole.log( delete Infinity ); // falseconsole.log( delete null ); // true,删除成功
プロトタイプの属性を削除する代わりにプロトタイプを削除:
function Person(){ } Person.prototype.name = "蚊子";console.log( delete Person.prototype ); // false,无法删除console.log( delete Object.prototype ); // false
配列と文字列の長さを削除する場合:
var arr = [1, 2, 3, 4];console.log( arr.length ); // 4console.log( delete arr.length ); // false,删除失败console.log( arr.length ); // 4var str = 'abcdefg';console.log( str.length ); // 7console.log( delete str.length ); // false,删除失败console.log( str.length ); // 7
obj で削除属性の削除:
var obj = {name:'wenzi', age:25};console.log( obj.name ); // wenziconsole.log( delete obj.name ); // true,删除成功console.log( obj.name ); // undefinedconsole.log( obj ); // { age:25 }
インスタンス オブジェクトの属性を削除する場合、次の出力からわかるように、delete を使用して属性を削除すると、インスタンス オブジェクト自体の属性のみが削除され、プロトタイプの属性は削除されません。プロトタイプ上の属性を再度削除しても、プロトタイプ上の属性またはその属性のメソッドを削除したい場合は、Person.prototype のみを削除できます。 name:
function Person(){ this.name = 'wenzi'; } Person.prototype.name = '蚊子';var student = new Person();console.log( student.name ); // wenziconsole.log( delete student.name ); // true,删除成功console.log( student.name ); // 蚊子console.log( delete student.name ); // trueconsole.log( student.name ); // 蚊子console.log( delete Person.prototype.name ); // true,删除成功console.log( student.name ); // undefined
上の例では、一部の変数または属性は削除できますが、一部の変数または属性は削除できるかどうかを決定します。
ECMA-262 第 5 版は、JS オブジェクト プロパティ (JS エンジンで使用され、外部から直接アクセスできない) の特性を定義します。 ECMAScript には、データ プロパティとアクセサー プロパティの 2 種類のプロパティがあります。
データ属性は、値の読み取りまたは書き込みができるデータ値を含む場所を指します。この属性には、その動作を説明する 4 つの特性があります。 [[構成可能]]: できることを示します。 delete 演算子を使用して削除および再定義できるかどうか、またはアクセサー プロパティとして変更できるかどうか。デフォルトは true;
[[Enumberable]]: for-in ループを通じて属性を返すことができるかどうかを示します。デフォルトは true; [[Writable]]: 属性の値を変更できるかどうかを示します。デフォルトは true;
[[Value]]: この属性のデータ値が含まれます。この値は読み取り/書き込み可能です。デフォルトは未定義です。たとえば、name 属性は上記のインスタンス オブジェクト person で定義されており、その値は 'wenzi' です。この値の変更はすべてこの場所で行われます
オブジェクト属性のデフォルトの特性を変更するには (デフォルトは true)、Object.defineProperty() メソッドを呼び出すことができます。このメソッドは、プロパティが配置されているオブジェクト、プロパティ名、および記述子オブジェクト (構成可能、enumberable、書き込み可能、および値の 1 つまたは両方である必要があります) の 3 つのパラメーターを受け取ります。より多くの値を設定できます)。
は次のとおりです:
var person = {};Object.defineProperty(person, 'name', { configurable: false, // 不可删除,且不能修改为访问器属性 writable: false, // 不可修改 value: 'wenzi' // name的值为wenzi});console.log( person.name); // wenziconsole.log( delete person.name ); // false,无法删除person.name = 'lily';console.log( person.name ); // wenzi
person.name の値は削除もリセットも有効ではないことがわかります。これは、defineProperty 関数の呼び出しによってオブジェクトのプロパティの特性が変更されるためです。 false に設定すると、それはできません。次に、defineProperty を使用して true に変更します (実行すると、エラーが報告されます: Uncaught TypeError: Cannot redefine property: name);
2.2 アクセサー プロパティ
如若像下面的方式进行定义,访问器属性和数据属性同时存在:
var o = {};Object.defineProperty(o, 'name', { value: 'wenzi', set: function(name) { myName = name; }, get: function() { return myName; } });
上面的代码看起来貌似是没有什么问题,但是真正执行时会报错,报错如下:
Uncaught TypeError: Invalid property. A property cannot both have accessors and be writable or have a value
对于数据属性,可以取得:configurable,enumberable,writable和value;
对于访问器属性,可以取得:configurable,enumberable,get和set。
由此我们可知:一个变量或属性是否可以被删除,是由其内部属性Configurable进行控制的,若Configurable为true,则该变量或属性可以被删除,否则不能被删除。
可是我们应该怎么获取这个Configurable值呢,总不能用delete试试能不能删除吧。有办法滴!!
ES5为我们提供了Object.getOwnPropertyDescriptor(object, property)来获取内部属性。
如:
var person = {name:'wenzi'};var desp = Object.getOwnPropertyDescriptor(person, 'name'); // person中的name属性console.log( desp ); // {value: "wenzi", writable: true, enumerable: true, configurable: true}
通过Object.getOwnPropertyDescriptor(object, property)我们能够获取到4个内部属性,configurable控制着变量或属性是否可被删除。这个例子中,person.name的configurable是true,则说明是可以被删除的:
console.log( person.name ); // wenziconsole.log( delete person.name ); // true,删除成功console.log( person.name ); // undefined
我们再回到最开始的那个面试题:
a = 1;var desp = Object.getOwnPropertyDescriptor(window, 'a');console.log( desp.configurable ); // true,可以删除var b = 2;var desp = Object.getOwnPropertyDescriptor(window, 'b');console.log( desp.configurable ); // false,不能删除
跟我们使用delete操作删除变量时产生的结果是一样的。
相关推荐:
JavaScript delete操作符应用实例_javascript技巧
以上がjsの削除演算子と内部属性インスタンスの詳細な説明の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。