ホームページ > 記事 > ウェブフロントエンド > vue.watch の実行についての非常に簡単な紹介
今回は、vue.watch の実装について非常に簡単に紹介し、vue.watch を実行する際の注意点を非常に簡単に紹介します。以下は実際的なケースです。見てみましょう。
1. オブジェクト初期化子を通じてオブジェクトを作成するときに指定します (リテラル値を通じてオブジェクトを作成するときに宣言することもできます)
(function () { var o = { a : 7, get b(){return this.a +1;},//通过 get,set的 b,c方法间接性修改 a 属性 set c(x){this.a = x/2} }; console.log(o.a); console.log(o.b); o.c = 50; console.log(o.a); })();
Chrome でのデバッグ ビューは次のとおりです:
さらにオブジェクトget 属性と set
属性がありますget
属性以及 set
属性
输出结果如下:
当然 get
语句与 set
语句可以声明多次用来对应多个 getter
和 setter
使用这种方法的好处是可以在声明属性的时候同时声明对应的 getter
和 setter
出力結果は次のとおりです:
もちろん、get
ステートメントと set ステートメントは、複数のステートメントに対応するように複数回宣言できます。このメソッドを <code>getter
および setter
とともに使用する利点は、対応する getter
とsetter
は、code 属性の宣言と同時に宣言できます。 ここで、o オブジェクトの get メソッドと set メソッドのメソッド名を "a" に変更できますかという質問がありました。 「.」でメソッドに直接アクセスして直接操作することができます
(function () { var o = { a : 7, get a(){return this.a +1;},//死循环 set a(x){this.a = x/2} }; console.log(o.a); console.log(o.b); o.c = 50; console.log(o.a); })();chromeを開いて作成したものを表示すると以下のようになります
この時のgetメソッドとsetメソッドが上記とは異なることが分かります。しかし、それらは本当に機能するのでしょうか? 答えは「ノー」です。 o.a を介して get ステートメントによって宣言された a メソッドを呼び出すと、このメソッドに入った後、このメソッドが呼び出され続け、無限ループが形成されます。これは最終的にメモリ オーバーフロー エラーを報告する無限ループにつながります。
新しい構文 (ES6): 現在、Firefox でのみサポートされており、他のブラウザではエラーが報告されます
(function () { var b = "bb"; var c = "cc"; var o = { a : 7, get [b](){return this.a +1;}, set [c](x){this.a = x/2}, }; console.log(o.a); console.log(o[b]); o["cc"] = 50; console.log(o.a); })();Firefox を開いてデバッグを表示します: 出力結果は次のとおりです:
2. Object.create メソッド
MDN からの引用:Object.create() メソッドは、指定されたプロトタイプといくつかの指定されたプロパティを持つオブジェクトを作成します。
概要
構文
Object.create(proto, [propertiesObject ])
Object.create メソッドを使用してパラメーターを渡す場合、そのパラメーターをプロトタイプとして使用してオブジェクトを作成できることは誰もが知っています。8 つのモードについて話しましょう。 JS でのオブジェクトの作成
2 番目のパラメーターはオプションであり、パラメーター オブジェクトは属性と値のセットです。値は、新しく作成されるオブジェクトの属性名になります。属性記述子(拡張データ記述子を含む)。属性記述子とは何かについての具体的な説明については、以下のコンテンツを参照してください。プロパティ記述子を通じて、新しく作成されたオブジェクトに get メソッドと set メソッドを追加できます
(function () { var o = null; o = Object.create(Object.prototype,//指定原型为 Object.prototype { bar:{ get :function(){ return 10; }, set : function (val) { console.log("Setting `o.bar` to ",val); } } }//第二个参数 ); console.log(o.bar); o.bar = 12; })();Chrome でのデバッグ ビューは次のとおりです:
新しく作成されたオブジェクトには、より一般的な get 属性と set 属性があることがわかります
出力結果は次のようになります上記の例は、get メソッドと set メソッドで使用される属性をターゲットにするために使用されていません
(function () { var o = null; o = Object.create(Object.prototype,//指定原型为 Object.prototype { bar:{ get :function(){ return this.a; }, set : function (val) { console.log("Setting `o.bar` to ",val); this.a = val; }, configurable :true } }//第二个参数 ); o.a = 10; console.log(o.bar); o.bar = 12; console.log(o.bar); })();
または:
(function () { var o = {a:10}; o = Object.create(o,//指定原型为 o 这里实际可以理解为继承 { bar:{ get :function(){ return this.a; }, set : function (val) { console.log("Setting `o.bar` to ",val); this.a = val; }, configurable :true } }//第二个参数 ); console.log(o.bar); o.bar = 12; console.log(o.bar); })();出力結果は次のとおりです:
を使用する利点この方法は高度に構成可能ですが、初心者は簡単に混乱する可能性があります。
3. Object.defineProperty メソッドを使用します🎜🎜🎜 MDN の引用: 🎜概要
Object.defineProperty() 方法直接在一个对象上定义一个新属性,或者修改一个已经存在的属性, 并返回这个对象。
语法
Object.defineProperty(obj, prop, descriptor)
参数
obj
需要定义属性的对象。
prop
需被定义或修改的属性名。
descriptor
需被定义或修改的属性的描述符。
(function () { var o = { a : 1}//声明一个对象,包含一个 a 属性,值为1 Object.defineProperty(o,"b",{ get: function () { return this.a; }, set : function (val) { this.a = val; }, configurable : true }); console.log(o.b); o.b = 2; console.log(o.b); })();
这个方法与前面两种的区别是:使用前面两种只能在声明定义的时候指定 getter 与 setter,使用该方法可以随时的添加或修改。
如果说需要一次性批量添加 getter 与 setter 也是没问题的,使用如下方法:
4.使用 Object.defineProperties方法
MDN:
概述
Object.defineProperties() 方法在一个对象上添加或修改一个或者多个自有属性,并返回该对象。
语法
Object.defineProperties(obj, props)
参数
obj
将要被添加属性或修改属性的对象
props
该对象的一个或多个键值对定义了将要为对象添加或修改的属性的具体配置
不难看出用法与 Object.defineProperty 方法类似
(function () { var obj = {a:1,b:"string"}; Object.defineProperties(obj,{ "A":{ get:function(){return this.a+1;}, set:function(val){this.a = val;} }, "B":{ get:function(){return this.b+2;}, set:function(val){this.b = val} } }); console.log(obj.A); console.log(obj.B); obj.A = 3; obj.B = "hello"; console.log(obj.A); console.log(obj.B); })();
输出结果如下:
5.使用 Object.prototype.__defineGetter__ 以及 Object.prototype.__defineSetter__ 方法
(function () { var o = {a:1}; o.__defineGetter__("giveMeA", function () { return this.a; }); o.__defineSetter__("setMeNew", function (val) { this.a = val; }) console.log(o.giveMeA); o.setMeNew = 2; console.log(o.giveMeA); })();
输出结果为1和2
查看 MDN 有如下说明:
什么是属性描述符
MDN:
对象里目前存在的属性描述符有两种主要形式:数据描述符和存取描述符。
数据描述符是一个拥有可写或不可写值的属性。
存取描述符是由一对 getter-setter 函数功能来描述的属性。
描述符必须是两种形式之一;不能同时是两者。
数据描述符和存取描述符均具有以下可选键值:
configurable
当且仅当这个属性描述符值为 true 时,该属性可能会改变,也可能会被从相应的对象删除。默认为 false。
enumerable
true 当且仅当该属性出现在相应的对象枚举属性中。默认为 false。
数据描述符同时具有以下可选键值:
value
与属性相关的值。可以是任何有效的 JavaScript 值(数值,对象,函数等)。默认为 undefined。
writable
true 当且仅当可能用 赋值运算符 改变与属性相关的值。默认为 false。
存取描述符同时具有以下可选键值:
get
一个给属性提供 getter 的方法,如果没有 getter 则为 undefined。方法将返回用作属性的值。默认为 undefined。
set
一个给属性提供 setter 的方法,如果没有 setter 则为 undefined。该方法将收到作为唯一参数的新值分配给属性。默认为 undefined。
以上是摘自MDN的解释,看起来是很晦涩的,具体什么意思呢:
首先我们从以上解释知道该匿名参数对象有个很好听的名字叫属性描述符,属性描述符又分成两大块:数据描述符以及存取描述符(其实只是一个外号,给指定的属性集合起个外号)。
数据描述符包括两个属性 : value 属性以及 writable 属性,第一个属性用来声明当前欲修饰的属性的值,第二个属性用来声明当前对象是否可写即是否可以修改
存取描述符就包括 get 与 set 属性用来声明欲修饰的象属性的 getter 及 setter
属性描述符内部,数据描述符与存取描述符只能存在其中之一,但是不论使用哪个描述符都可以同时设置 configurable 属性以及enumerable
属性。configurable
属性用来声明欲修饰的属性是否能够配置,仅有当其值为 true 时,被修饰的属性才有可能能够被删除,或者重新配置。enumerable
属性用来声明欲修饰属性是否可以被枚举。
知道了什么是属性描述符,我们就可以开始着手创建一些对象并开始配置其属性
创建属性不可配置不可枚举的对象
//使用默认值配置 (function () { var obj = {};//声明一个空对象 Object.defineProperty(obj,"key",{ value:"static" //没有设置 enumerable 使用默认值 false //没有 configurable 使用默认值 false //没有 writable 使用默认值 false }); console.log(obj.key); //输出 “static” obj.key = "new" //尝试修改其值,修改将失败,因为 writable 为 false console.log(obj.key); //输出 “static” obj.a = 1;//动态添加一个属性 for(var item in obj){ //遍历所有 obj 的可枚举属性 console.log(item); }//只输出一个 “a” 因为 “key”的 enumerable为 false })();
//显示配置 等价于上面 (function () { var obj = {}; Object.defineProperty(obj,"key",{ enumerable : false, configurable : false, writable : false, value : "static" }) })();
//等价配置 (function () { var o = {}; o.a = 1; //等价于 Object.defineProperty(o,"a",{value : 1, writable : true, configurable : true, enumerable : true}); Object.defineProperty(o,"a",{value :1}); //等价于 Object.defineProperty(o,"a",{value : 1, writable : false, configurable : false, enumerable : false}); })();
Enumerable 特性
属性特性 enumerable 决定属性是否能被 for...in 循环或 Object.keys 方法遍历得到
(function () { var o = {}; Object.defineProperty(o,"a",{value :1,enumerable :true}); Object.defineProperty(o,"b",{value :2,enumerable :false}); Object.defineProperty(o,"c",{value :2});//enumerable default to false o.d = 4;//如果直接赋值的方式创建对象的属性,则这个属性的 enumerable 为 true for(var item in o){ //遍历所有可枚举属性包括继承的属性 console.log(item); } console.log(Object.keys(o));//获取 o 对象的所有可遍历属性不包括继承的属性 console.log(o.propertyIsEnumerable('a'));//true console.log(o.propertyIsEnumerable('b'));//false console.log(o.propertyIsEnumerable('c'));//false })();
输出结果如下:
Configurable 特性
(function () { var o = {}; Object.defineProperty(o,"a",{get: function () {return 1;}, configurable : false} ); //enumerable 默认为 false, //value 默认为 undefined, //writable 默认为 false, //set 默认为 undefined //抛出异常,因为最开始定义了 configurable 为 false,故后期无法对其进行再配置 Object.defineProperty(o,"a",{configurable : true} ); //抛出异常,因为最开始定义了 configurable 为 false,故后期无法对其进行再配置,enumerable 的原值为 false Object.defineProperty(o,"a",{enumerable : true} ); //抛出异常,因为最开始定义了 configurable 为 false,set的原值为 undefined Object.defineProperty(o,"a",{set : function(val){}} ); //抛出异常,因为最开始定义了 configurable 为 false,故无法进行覆盖,尽管想用一样的来覆盖 Object.defineProperty(o,"a",{get : function(){return 1}}); //抛出异常,因为最开始定义了 configurable 为 false,故无法将其进行重新配置把属性描述符从存取描述符改为数据描述符 Object.defineProperty(o,"a",{value : 12}); console.log(o.a);//输出1 delete o.a; //想要删除属性,将失败 console.log(o.a);//输出1 })();
提高及扩展
1.属性描述符中容易被误导的地方之 writable 与 configurable
(function () { var o = {}; Object.defineProperties(o,{ "a": { value:1, writable:true,//可写 configurable:false//不可配置 //enumerable 默认为 false 不可枚举 }, "b":{ get :function(){ return this.a; }, configurable:false } }); console.log(o.a); //1 o.a = 2; //修改值成功,writable 为 true console.log(o.a); //2 Object.defineProperty(o,"a",{value:3});//同样为修改值成功 console.log(o.a); //3 //将其属性 b 的属性描述符从存取描述符重新配置为数据描述符 Object.defineProperty(o,"b",{value:3});//抛出异常,因为 configurable 为 false })();
2.通过上面的学习,我们都知道传递属性描述符参数时,是定义一个匿名的对象,里面包含属性描述符内容,若每定义一次便要创建一个匿名对象传入,将会造成内存浪费。故优化如下:
(function () { var obj = {}; //回收同一对象,即减少内存浪费 function withValue(value){ var d = withValue.d ||( withValue.d = { enumerable : false, configurable : false, writable : false, value :null } ); d.value = value; return d; } Object.defineProperty(obj,"key",withValue("static")) })();
相信看了本文案例你已经掌握了方法,更多精彩请关注php中文网其它相关文章!
推荐阅读:
以上がvue.watch の実行についての非常に簡単な紹介の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。