ホームページ ウェブフロントエンド jsチュートリアル ディスカッション: JavaScript ECAMScript5 の新機能 accessor_javascript スキルの取得/設定

ディスカッション: JavaScript ECAMScript5 の新機能 accessor_javascript スキルの取得/設定

May 16, 2016 pm 03:02 PM
javascript

EcmaScript5 の概要

まず、ECMAScript は魔法の馬であることを理解する必要があります。JavaScript または LiveScript が最初に作成されたのは Netscape であり、その後、Microsoft も独自の CENvi を作成しました。ブラウザ スクリプトはすべて独自の動作を行うため、この混乱を誰もが理解しているため、標準化の問題が議題に上ることになりました。 1997 年に、JavaScript 1.1 に基づく提案が欧州コンピュータ製造者協会 (欧州コンピュータ製造者協会) に提出され、最終的には ECMAScript と呼ばれる新しいスクリプト言語標準である ECMA-262 が全員で歌い踊りました。翌年、ISO/IEC (国際標準化機構および国際電気標準会議) も ECMAScript を標準として採用し、それ以来、主要なブラウザ メーカーがそれぞれの JavaScript 実装の基礎として ECMAScript を使用するようになりました。それ以外の場合は、ブラウザの互換性の問題もそれほど多く発生しません。

ECMAScript5 とは何ですか?名前が示すように、iPhone5 のようなこの奇妙なものの 5 番目のバージョンで、現在私たちがよく使用しているのは ECMAScript3 です。最初の 2 つのバージョンと比較すると、このバージョンはおもちゃではなく本物のプログラミング言語になっています。人気のある。

テキスト:

get/set についての私のこれまでの理解は間違っていました。get set はオブジェクトのプロパティ メソッドだと思っていました。他の人のブログを読んだ後、私もたくさんの質問をしましたが、今日私はシステムで多くのテストを行い、最終的にそれを理解しました。 (私は本を読んでデモを書いてテストに合格しました。間違いがあれば、批判して修正してください)

get/set アクセサーはオブジェクトのプロパティではなく、プロパティの特性です。誰もが明確に区別する必要があります。プロパティは内部でのみ使用されるため、JavaScript から直接アクセスすることはできません。属性を示すために、内部値は [[Value]] のように 2 組の大括弧で囲まれます。

1. これらの属性の特徴を簡単に紹介します (簡単な裏書きです)

(1) データ属性 - データ値の場所が含まれます。この場所に値を読み書きできます。

データ属性には、その動作を説明する 4 つの特性があります。

[[Configurable]]: 構成可能かどうか

[[Enumerable]]: 列挙可能かどうか

[[Writable]]: 読み取り可能かどうか

[[Value]]: 属性値

(2) アクセサ属性属性 - データ値は含まず、ゲッター関数とセッター関数が含まれます (これら 2 つの関数は必要ありません)

アクセサ プロパティには、その動作を説明する 4 つの特性もあります。

[[Configurable]]: 構成可能かどうか

[[Enumerable]]: 列挙可能かどうか

[[Get]]: プロパティの読み取り時に呼び出される関数、デフォルトは未定義です

[[Set]]: 属性を書き込むときに呼び出される関数、デフォルトは未定義です。

2. ここでは、get/set アクセサー
と呼ばれるものである [[Get]]/[[Set]] に焦点を当てます。

まず、本書で言及されている get/set アクセサーの動作特性について説明します。get/set アクセサーは定義する必要がなく、定義せずに属性値の読み取りと書き込みが可能です。 1 つだけ定義することもできます。 get のみが定義されている場合、記述された属性は読み取りのみ可能であり、書き込みはできません。 set のみが定義されている場合、記述された属性は書き込みのみ可能であり、読み取りはできません。

(1) オリジナルの get set メソッドは次のようなものです:

function Foo(val){
var value=val;
this.getValue=function(){
return value;
};
this.setValue=function (val){
value=val;
};
}
var obj=new Foo("hello");
alert(obj.getValue());//"hello"
obj.setValue("hi");
alert(obj.getValue());//"hi" 
ログイン後にコピー

上記のコードは、クロージャ スコープを使用して実装された get set メソッドにすぎません。このメソッドは、属性の特性ではなく、インスタンス オブジェクトの属性メソッドであることに注意してください。定義されていない場合、値
にはアクセスできません。

function Foo(val){
var value=val;
/* this.getValue=function(){
return value;
};
this.setValue=function (val){
value=val;
};
*/
}
var obj=new Foo("hello");
alert( obj.value);//undefined
ログイン後にコピー

次の例もオブジェクトのプロパティ メソッドであり、プロパティ特性ではありません。

var obj={
name:"john",
get:function (){
return this.age;
}//只定义了get ,没有定义set,但是仍然可以读,写,name属性,即使这里是age
//这里这样定义的方法不会影响属性的get,set 特性。只是普通的对象属性
};
alert(obj.name);//john 可读
obj.name="jack";//可写
alert(obj.name);//jack 
ログイン後にコピー

(2) アクセサ属性の特性としてアクセサを取得/設定します。

繰り返しますが、これらはオブジェクトのプロパティではなく、プロパティを読み書きできるかどうか、またその方法を決定します。設定しなくても通常の読み書きと同じで大丈夫です(属性は読み込めます

)

書き込み、読み取り、および書き込みアクセスは属性自体の値です)

属性の get/set プロパティを変更するには、次の 2 つの方法があります:

a. Object.defineProperty()

を使用するだけです。
var object={
_name:"Daisy" 
};
Object.defineProperty(object,"name",{//这里的方法名name,就表示定义了一个name属性(因此才能通过object.name访问),只定义了getter访问器,没有定义[[value]]值
get:function (){//只定义了get 特性,因此只能读不能写
return this._name;
}
});
alert(object.name);//"Daisy"
object.name="jack";//只定义了getter访问器,因此写入失效
alert(object.name);//"Daisy" 
ログイン後にコピー

Object.defineProperty(object, pro, {}) のプロパティ名は、object.pro によってアクセスされるプロパティに対応する必要があることに注意してください

b. get set キーワードを使用します:

var object={
_name:"Daisy",
get name(){//这里的方法名name ,就表示定义了一个name属性(因此才能通过object.name访问),只定义了getter访问器,没有定义[[value]]值
return this._name;
}//get,set方法只是属性的特性 ,不是对象方法,决定属性能否、怎么读写
};
alert(object.name);// Daisy这里去掉下划线 方法就是Daisy ;加上就是undefined
object.name="jack";//只定义了getter访问器,因此只能读不能写
alert(object.name);//Daisy 
ログイン後にコピー

以上两种方法等效。注意的是以上两种方法object对象当中都将有有两个属性:_name(有初始值) name(无初始值),通过浏览器控制台可以看到

那么这个name属性实在什么时候定义的呢?我们知道Object.defineProperty(object,pro,{})可以给对象定义一个新属性pro,既然get pro(){}/set pro(){}和Object.defineProperty(object,pro,{})等效,则也会定义一个新属性pro .这就是为什么object里面有两个属性的原因。

(3)在此篇文章中网络之美 JavaScript中Get和Set访问器的实现代码关于标准标准的Get和Set访问器的实现:引发的思考

我自己也写了一个一样的例子

function Foo(val){
this.value=val;//定义了value属性 并没有定义_value
}
Foo.prototype={
set value(val){//注意方法名和属性名相同,在prototype里定义了value属性
this._value=val;
},
get value(){//方法名和属性名相同,在prototype里面定义了value属性和它的get 特性
return this._value;
}
}; //访问器返回和设置的都是_name,这里并没有定义_name属性为什么也可以读可以写????     
var obj=new Foo("hello");     
alert(obj.value);//"hello"     
obj.value="yehoo";     
alert(obj.value);//"yehoo" 
ログイン後にコピー

为了解决以上这个疑问,做了很多测试,我们一一来看:

先看这个例子,在prototype里面只定义get 特性,在obj.value读value属性时,在实例里面寻找没有,然后在原型里面找到,调用的是原型的get方法,只能读不能写

function Foo(val){
this._value=val;//这里 的属性是带下划线的,初始化实例对象的_value属性,_value属性可读可写
}
Foo.prototype={
// set value(val){//注意方法名和属性名相同,在prototype里定义了value属性
// this._value=val;
// },
get value(){//方法名和属性名相同,在prototype里面定义了value属性和它的get 特性
return this._value;
}
}; 
var obj=new Foo("hello");
alert(obj.value);//hello 访问的是prototype里面的value 属性
obj.value="yehoo";//只定义了name 属性的get 特性,因此只能读不能写,写入失效
alert(obj.value);//hello 
ログイン後にコピー

如果构造函数里面this._value 去掉下划线,在prototype里面定义的value属性,定义了get 特性。依然可以控制value属性的读写 。也就是说obj.value访问属性时,会调用get方法,先在对象本身寻找,如果没有,再到prototype寻找,如果都没有才算没有定义,默认的既可读又可写

function Foo(val){
this.value=val;//在原型里面只定义了value的get特性,因此这里写入失效
}
Foo.prototype={
// set value(val){//注意方法名和属性名相同,在prototype里定义了value属性的set特性
// this._value=val;
//},
//value:"hah",//即使手动写入value值,由于get方法返回的是this._value,因此也不能正确读取value:"hah"
//只要声明了get pro (){}和set pro (){}属性就都能读能写,但是如果函数定义错误,依然不能按要求访问到正确的属性值
get value(){//方法名和属性名相同,在prototype里面定义了value属性和它的get 特性
return this._value;
}
}; 
var obj=new Foo("hello");//"hello"没有写入成功
alert(obj.value);//undefined 
obj.value="yehoo";//只定义了get 特性,因此只能读不能写,写入失效
alert(obj.value);//undefined 
ログイン後にコピー

为了证明上面例子是可读不可写的:手动写入_value:"hah",就可以读取value 但不能写入。

function Foo(val){
this.value=val;//在原型里面只定义了value的get特性,因此这里写入失效
}
Foo.prototype={
// set value(val){//注意方法名和属性名相同,在prototype里定义了value属性的set特性
// this._value=val;
//},
_value:"hah",//即使手动写入value值,由于get方法返回的是this._value,因此也不能正确读取value:"hah"
//只要声明了get pro (){}和set pro (){}属性就都能读能写,但是如果函数定义错误,依然不能按要求访问到正确的属性值
get value(){//方法名和属性名相同,在prototype里面定义了value属性和它的get 特性
return this._value;
}
}; 
var obj=new Foo("hello");//"hello"没有写入成功
alert(obj.value);//"hah" 
obj.value="yehoo";//只定义了get 特性,因此只能读不能写,写入失效
alert(obj.value);//"hah" 
ログイン後にコピー

如果手动写入的是value:"hah",那么可以争取读取value的值吗?由于get方法返回的this._value并没有定义,obj.value读取value值调用get value(){}方法失效,但是value仍然不能写入。

function Foo(val){
this.value=val;//在原型里面只定义了value的get特性,因此这里写入失效
}
Foo.prototype={
// set value(val){//注意方法名和属性名相同,在prototype里定义了value属性的set特性
// this._value=val;
//},
value:"hah",//即使手动写入value值,由于get方法返回的是this._value,因此也不能正确读取value:"hah"
//只要声明了get pro (){}和set pro (){}属性就都能读能写,但是如果函数定义错误,依然不能按要求访问到正确的属性值
get value(){//方法名和属性名相同,在prototype里面定义了value属性和它的get 特性
return this._value;
}
}; 
var obj=new Foo("hello");//"hello"没有写入成功
alert(obj.value);//undefined 读取失效 因为只要obj.value就会调用get ,而get返回的是this._value,没有这个值,因此undefined
obj.value="yehoo";//只定义了get 特性,因此只能读不能写,写入失效
alert(obj.value);//undefined 
ログイン後にコピー

再看这个例子,get set 都定义了,但是返回没有定义的this._value。可以发现value既可读又可写。去掉原型里面的get set方法,依然可读可写

function Foo(val){
this.value=val;
}
Foo.prototype={
set value(val){
this._value=val;
},
get value(){
return this._value;
}
}; 
var obj=new Foo("hello");
alert(obj.value);//hello 
obj.value="yehoo";
alert(obj.value);//yehoo 
function Foo(val){
this.value=val;
}
//和平时的操作是一样的了,就是回到了不定义get /set访问器特性的默认状态
var obj=new Foo("hello");
alert(obj.value);//hello 
obj.value="yehoo";
alert(obj.value);//yehoo 
ログイン後にコピー

总结

只声明了get pro(){}属性 可读不可写;

只声明 set pro(){}属性可写不可读。

如果都不声明,属性可读可写;

如果都声明就按照,get set 定义的方法,读写;

如果都声明了,但是定义的读写方法不能正确读写,get/set失效。变成默认的可读可写

在prototype里面定义的value属性,定义了get 特性。依然可以控制value属性的读写 。也就是说obj.value访问属性时,会调用get方法,先在对象本身寻找,如果没有,再到prototype寻找,如果都没有才算没有定义,默认的既可读又可写。

补充:

不管是用get pro(){}/set pro (){} 

还是用Object.defineProperty(object,pro,{


         get:function (){
           return this._name;
           } });
ログイン後にコピー

pro不能和 return this. 后面的属性一样,不然会报下面的错误:(具体我也不知道为什么,好像是自身调用引起的栈溢出)

经大神指正,明白为什么这里报错:在get value(){}方法里返回 this.value,就会又去调用value的get 方法,因此陷入死循环,造成方法栈溢出。

このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。

ホット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ヘンタイを無料で生成します。

ホットツール

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無料のコードエディター

SublimeText3 中国語版

SublimeText3 中国語版

中国語版、とても使いやすい

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

SublimeText3 Mac版

SublimeText3 Mac版

神レベルのコード編集ソフト(SublimeText3)

WebSocket と JavaScript を使用してオンライン音声認識システムを実装する方法 WebSocket と JavaScript を使用してオンライン音声認識システムを実装する方法 Dec 17, 2023 pm 02:54 PM

WebSocket と JavaScript を使用してオンライン音声認識システムを実装する方法 はじめに: 技術の継続的な発展により、音声認識技術は人工知能の分野の重要な部分になりました。 WebSocket と JavaScript をベースとしたオンライン音声認識システムは、低遅延、リアルタイム、クロスプラットフォームという特徴があり、広く使用されるソリューションとなっています。この記事では、WebSocket と JavaScript を使用してオンライン音声認識システムを実装する方法を紹介します。

WebSocket と JavaScript: リアルタイム監視システムを実装するための主要テクノロジー WebSocket と JavaScript: リアルタイム監視システムを実装するための主要テクノロジー Dec 17, 2023 pm 05:30 PM

WebSocketとJavaScript:リアルタイム監視システムを実現するためのキーテクノロジー はじめに: インターネット技術の急速な発展に伴い、リアルタイム監視システムは様々な分野で広く利用されています。リアルタイム監視を実現するための重要なテクノロジーの 1 つは、WebSocket と JavaScript の組み合わせです。この記事では、リアルタイム監視システムにおける WebSocket と JavaScript のアプリケーションを紹介し、コード例を示し、その実装原理を詳しく説明します。 1.WebSocketテクノロジー

WebSocketとJavaScriptを使ったオンライン予約システムの実装方法 WebSocketとJavaScriptを使ったオンライン予約システムの実装方法 Dec 17, 2023 am 09:39 AM

WebSocket と JavaScript を使用してオンライン予約システムを実装する方法 今日のデジタル時代では、ますます多くの企業やサービスがオンライン予約機能を提供する必要があります。効率的かつリアルタイムのオンライン予約システムを実装することが重要です。この記事では、WebSocket と JavaScript を使用してオンライン予約システムを実装する方法と、具体的なコード例を紹介します。 1. WebSocket とは何ですか? WebSocket は、単一の TCP 接続における全二重方式です。

JavaScript と WebSocket を使用してリアルタイムのオンライン注文システムを実装する方法 JavaScript と WebSocket を使用してリアルタイムのオンライン注文システムを実装する方法 Dec 17, 2023 pm 12:09 PM

JavaScript と WebSocket を使用してリアルタイム オンライン注文システムを実装する方法の紹介: インターネットの普及とテクノロジーの進歩に伴い、ますます多くのレストランがオンライン注文サービスを提供し始めています。リアルタイムのオンライン注文システムを実装するには、JavaScript と WebSocket テクノロジを使用できます。 WebSocket は、TCP プロトコルをベースとした全二重通信プロトコルで、クライアントとサーバー間のリアルタイム双方向通信を実現します。リアルタイムオンラインオーダーシステムにおいて、ユーザーが料理を選択して注文するとき

JavaScript と WebSocket: 効率的なリアルタイム天気予報システムの構築 JavaScript と WebSocket: 効率的なリアルタイム天気予報システムの構築 Dec 17, 2023 pm 05:13 PM

JavaScript と WebSocket: 効率的なリアルタイム天気予報システムの構築 はじめに: 今日、天気予報の精度は日常生活と意思決定にとって非常に重要です。テクノロジーの発展に伴い、リアルタイムで気象データを取得することで、より正確で信頼性の高い天気予報を提供できるようになりました。この記事では、JavaScript と WebSocket テクノロジを使用して効率的なリアルタイム天気予報システムを構築する方法を学びます。この記事では、具体的なコード例を通じて実装プロセスを説明します。私たちは

簡単な JavaScript チュートリアル: HTTP ステータス コードを取得する方法 簡単な JavaScript チュートリアル: HTTP ステータス コードを取得する方法 Jan 05, 2024 pm 06:08 PM

JavaScript チュートリアル: HTTP ステータス コードを取得する方法、特定のコード例が必要です 序文: Web 開発では、サーバーとのデータ対話が頻繁に発生します。サーバーと通信するとき、多くの場合、返された HTTP ステータス コードを取得して操作が成功したかどうかを判断し、さまざまなステータス コードに基づいて対応する処理を実行する必要があります。この記事では、JavaScript を使用して HTTP ステータス コードを取得する方法を説明し、いくつかの実用的なコード例を示します。 XMLHttpRequestの使用

JavaScriptでinsertBeforeを使用する方法 JavaScriptでinsertBeforeを使用する方法 Nov 24, 2023 am 11:56 AM

使用法: JavaScript では、insertBefore() メソッドを使用して、DOM ツリーに新しいノードを挿入します。このメソッドには、挿入される新しいノードと参照ノード (つまり、新しいノードが挿入されるノード) の 2 つのパラメータが必要です。

JavaScript で HTTP ステータス コードを簡単に取得する方法 JavaScript で HTTP ステータス コードを簡単に取得する方法 Jan 05, 2024 pm 01:37 PM

JavaScript で HTTP ステータス コードを取得する方法の紹介: フロントエンド開発では、バックエンド インターフェイスとの対話を処理する必要があることが多く、HTTP ステータス コードはその非常に重要な部分です。 HTTP ステータス コードを理解して取得すると、インターフェイスから返されたデータをより適切に処理できるようになります。この記事では、JavaScript を使用して HTTP ステータス コードを取得する方法と、具体的なコード例を紹介します。 1. HTTP ステータス コードとは何ですか? HTTP ステータス コードとは、ブラウザがサーバーへのリクエストを開始したときに、サービスが

See all articles