這次帶給大家JS加入getter setter總結,JS加入getter setter的注意事項有哪些,以下就是實戰案例,一起來看一下。
定義getter 與setter<br>
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
語句可以宣告多次用來對應多個getter
和setter<br>
使用這種方法的好處是可以在宣告屬性的時候同時宣告對應的getter
和setter<br>
這裡就有人問了,能不能將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方法,進入到該方法後遇到this.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 方法傳遞一個參數的時候可以建立一個以該參數為原型的對象淺談JS 建立對象的8 種模式Object.create() 方法建立一個擁有指定原型和若干個指定屬性的物件。
語法Object.create(proto, [ propertiesObject ])
第二個參數是可選項,是一個匿名的參數對象,該參數對像是一組屬性與值,該對象的屬性名稱將是新建立的對象的屬性名稱,值是屬性描述符(包擴資料描述符或存取描述符,具體解釋看後面的內容什麼是屬性描述符)。
透過屬性描述子我們可以實作為新建立的物件新增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); })();
輸出結果如下:
使用這種方式的好處是可配置性高,但初學者容易迷糊。
引用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中文网其它相关文章!
推荐阅读:
以上是JS添加getter+setter總結的詳細內容。更多資訊請關注PHP中文網其他相關文章!

如何使用JS和百度地图实现地图平移功能百度地图是一款广泛使用的地图服务平台,在Web开发中经常用于展示地理信息、定位等功能。本文将介绍如何使用JS和百度地图API实现地图平移功能,并提供具体的代码示例。一、准备工作使用百度地图API前,首先需要在百度地图开放平台(http://lbsyun.baidu.com/)上申请一个开发者账号,并创建一个应用。创建完成

如何使用JS和百度地图实现地图热力图功能简介:随着互联网和移动设备的迅速发展,地图成为了一种普遍的应用场景。而热力图作为一种可视化的展示方式,能够帮助我们更直观地了解数据的分布情况。本文将介绍如何使用JS和百度地图API来实现地图热力图的功能,并提供具体的代码示例。准备工作:在开始之前,你需要准备以下事项:一个百度开发者账号,并创建一个应用,获取到相应的AP

js字符串转数组的方法:1、使用“split()”方法,可以根据指定的分隔符将字符串分割成数组元素;2、使用“Array.from()”方法,可以将可迭代对象或类数组对象转换成真正的数组;3、使用for循环遍历,将每个字符依次添加到数组中;4、使用“Array.split()”方法,通过调用“Array.prototype.forEach()”将一个字符串拆分成数组的快捷方式。

如何使用JS和百度地图实现地图多边形绘制功能在现代网页开发中,地图应用已经成为常见的功能之一。而地图上绘制多边形,可以帮助我们将特定区域进行标记,方便用户进行查看和分析。本文将介绍如何使用JS和百度地图API实现地图多边形绘制功能,并提供具体的代码示例。首先,我们需要引入百度地图API。可以利用以下代码在HTML文件中导入百度地图API的JavaScript

js中new操作符做了:1、创建一个空对象,这个新对象将成为函数的实例;2、将新对象的原型链接到构造函数的原型对象,这样新对象就可以访问构造函数原型对象中定义的属性和方法;3、将构造函数的作用域赋给新对象,这样新对象就可以通过this关键字来引用构造函数中的属性和方法;4、执行构造函数中的代码,构造函数中的代码将用于初始化新对象的属性和方法;5、如果构造函数中没有返回等等。

这篇文章主要为大家详细介绍了js实现打字小游戏,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下。

php在特定情况下可以读js内部的数组。其方法是:1、在JavaScript中,创建一个包含需要传递给PHP的数组的变量;2、使用Ajax技术将该数组发送给PHP脚本。可以使用原生的JavaScript代码或者使用基于Ajax的JavaScript库如jQuery等;3、在PHP脚本中,接收传递过来的数组数据,并进行相应的处理即可。

js全称JavaScript,是一种具有函数优先的轻量级,直译式、解释型或即时编译型的高级编程语言,是一种属于网络的高级脚本语言;JavaScript基于原型编程、多范式的动态脚本语言,并且支持面向对象、命令式和声明式,如函数式编程。


熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

AI Hentai Generator
免費產生 AI 無盡。

熱門文章

熱工具

SublimeText3 Mac版
神級程式碼編輯軟體(SublimeText3)

SAP NetWeaver Server Adapter for Eclipse
將Eclipse與SAP NetWeaver應用伺服器整合。

MinGW - Minimalist GNU for Windows
這個專案正在遷移到osdn.net/projects/mingw的過程中,你可以繼續在那裡關注我們。 MinGW:GNU編譯器集合(GCC)的本機Windows移植版本,可自由分發的導入函式庫和用於建置本機Windows應用程式的頭檔;包括對MSVC執行時間的擴展,以支援C99功能。 MinGW的所有軟體都可以在64位元Windows平台上運作。

Dreamweaver CS6
視覺化網頁開發工具

WebStorm Mac版
好用的JavaScript開發工具