ES5 getter setter

    最近在学习vuejs,了解到内部实现使用到了es5的Getters和Setters。之前看高程的时候,没有重视这块,今天查看一下文档,了解了他们的作用,再次记录一下,可供以后查看和共享。

  定义Getters和Setters:(一共有三种定义方法)

 第一种方法: 使用对象字面量创建对象时,可以像下面定义set 和set一样定义,

 1 var obj = {
 2     "a": 1,
 3     get b(){
 4         return this.a + 1;
 5     },
 6     set c(val){
 7         this.a = val + this.a;
 8     }
 9 };
10 
11 console.log(obj.a);   //初始值为1
12 console.log(obj.b);   //2
13 obj.c = 3;
14 console.log(obj.a);   //4

  第二种方法:通过Object.defineProperty(...)来定义

 1 var d = Date.prototype;
 2 
 3 Object.defineProperty(d, "year", {
 4     get : function() {
 5         return this.getFullYear();
 6     },
 7     set: function(val) {
 8         this.setFullYear(val);
 9     }
10 });
11 
12 var date = new Date();
13 console.log("*********");
14 console.log(date.year);   //2016
15 console.log("*********");

第三种方式:

 1 function Filed(val){
 2     var value = val;
 3     this.getValue = function(){
 4         return value;
 5     };
 6     this.setValue = function(val){
 7         value = value = val;
 8     };
 9 }
10 
11 var f = new Filed(20);
12 console.log("\n**********************");
13 console.log(f.getValue());         //20
14 f.setValue(30);
15 console.log(f.getValue());         //30

Getters和Setters可以做什么?

  目的:给js语言增加覆盖对象单个属性默认的[[Get]]和[[Put]]能力。

  实际上,Getters和Setters都是对象上的属性,通过Getters可以调用对象上隐藏的函数来获取值,通过Setters调用隐藏的函数,来为对象属性赋值。

  我们知道对象的属性描述符有value、writable、configurable和enumerable。Getters和Setter也可被理解为对象的存取描述符。如果一个对象定义了Getter和Setter,value和writable会被忽略,js只考虑Getter、Setter、configurable和enumerable。

  

 1 var obj = {
 2     get a(){
 3         return 2;
 4     }
 5 };
 6 
 7 Object.defineProperty(obj, "b", {
 8     get: function(){
 9         return this.a * 4;
10     },
11     enumerable: true
12 });
13 
14 console.log(obj.a);   //2
15 console.log(obj.b);   //8
16 obj.a = 4;
17 console.log(obj.a);   //2

  在16行的时候,我们对a进行赋值,但是在17行的时候,依旧输出了2,,这是因为一旦存在存在存取描述符,并且仅设有Getter的话(即便设有Setter),对该属性的赋值会被默认忽略。

 1 var obj = {
 2     get a(){
 3         return 2;
 4     },
 5     set c(val){
 6         this.a = 3;
 7     }
 8 };
 9 
10 Object.defineProperty(obj, "b", {
11     get: function(){
12         return this.a * 4;
13     },
14     enumerable: true
15 });
16 
17 console.log(obj.a);   //2
18 console.log(obj.b);   //8
19 //obj.a = 4;
20 obj.c = 4;
21 console.log(obj.a);   //2

  实际使用代码如下:

 1 var myObject = {
 2     // define a getter for `a`
 3     get a() {
 4         return this._a_;
 5     },
 6 
 7     // define a setter for `a`
 8     set a(val) {
 9         this._a_ = val * 2;
10     }
11 };
12 
13 myObject.a = 2;
14 
15 console.log(myObject.a); // 4

  通过Setter和Getter,我们可以动态设置和获取对象属性的值得效果:

 1 var expr = "foo";
 2 var obj = {
 3     a: "aa",
 4     set [expr](val){
 5         this.a = val;
 6     },
 7     get [expr](){
 8         return expr
 9     }
10 };
11 
12 obj.foo="bb";
13 console.log(obj.a);   //bb
14 console.log(obj[expr]);   //foo

对于上面的动态设置和获取,不晓得实际用途。

js的[[Get]]和[[Put]]操作

Getter和Setter会对js对象属性的存取产生怎样的影响呢?

[[Get]]操作:

1 var obj = {
2     a: 2  
3 };
4 console.log(obj.a);    //2

上面代码的背后的机制:

执行的时候,JavaScript 会在对象 obj上执行一次 [[Get]] 操作。JavaScript 内置的 [[Get]] 操作首先根据属性名称检查对象本身是否有该属性,如果这时候找到了,那么就返回它的值;如果没找到,那么会通过该对象的Prototype 链继续向上查找,直到顶层的 Object.prototype。见下面代码:

1 var OldObj = function(){};
2 OldObj.prototype.a = 2;
3 var obj = new OldObj();
4 console.log(obj.a);   //2

[[put]]操作:

1 var obj = {
2     a: 2  
3 };
4 obj.a = 3;

背后的机制:

首先,JavaScript 会触发一个 [[Put]] 操作,它的行为会根据要赋值的属性是否已经直接存在于该对象上而有所不同。如果该属性已经存在了,[[Put]] 操作会执行如下步骤:

  1. 该属性是否已经定义了 Setter,如果已经定义了,那么调用它;
  2. 该属性的属性描述符 (Property Descriptor)是否定义了 writable: false,如果是,那么赋值操作被忽略,如果是 strict mode,那么会抛出 TypeError 异常;
  3. 如果没有上述情况,那么给已存在的属性赋值。

如果被赋值的属性不是直接存在于对象上:

  1. [[Put]] 操作首先会搜索 Prototype 链,如果没有找到 foo,那么就在被赋值的对象上直接创建 foo,并赋值为 bar
  2. 如果在 Prototype 链上找到了 foo,代码的行为就会变得诡异起来,我们回头再看。在此之前,先来了解一个概念,叫做变量隐藏 (Variable Shadowing)。当一个变量既直接存在于对象本身,又存在于对象的 Prototype 链,那我们就可以说对象本身的属性 foo 隐藏了存在于 Prototype 链的变量 foo。理解了这个概念,我们再来看当变量 foo 在 Prototype 链上存在的的时候,给 foo 赋值可能带来的三种结果:
    1. 如果 foo 在 Prototype 链上存在,并且它没有被定义为只读的 (writable: false),那么一个名叫 foo 的属性会被直接添加到 myObject,从而造成 变量隐藏 (Shadowing)
    2. 如果 foo 在 Prototype 链上存在,并且被标记为只读的 (writable: false),那么对 foo 的赋值操作会被忽略;如果是 strict mode,那么会抛出异常;
    3. 如果 foo 在 Prototype 链上存在,并且它具有 Setter,那么 Setter 始终会被调用,也就是说没有属性会被直接添加到 myObject 上,也不会发生变量隐藏。也许你还记得,当对象属性 Setter 存在的时候,给该属性赋值,不会检查 writable

原文地址:js Getters和Setters

转载于:https://www.cnblogs.com/yanyalun/p/5549883.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/271697.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

python 调用bat失败_要想顺利通过Python面试,你最起码需要达到白银段位!

近几年 Python 非常热门,在学术界和产业界的使用率显著提高。目前学习Python的人数日益增多,Python在近3年的编程语言受欢迎度中一直处于榜首。今天我们就来讲讲在产业界,需要具备哪些能力才能获得一个满意的 Python 相关岗位 Offer。Python基…

多线程售票demo,用ReentrantLock实现

代码: public class TicketReentLockDemo implements Runnable {private int ticketTotal 100;private Lock lock new ReentrantLock();Overridepublic void run() {while (ticketTotal > 0) {try {lock.lock();if (ticketTotal > 0) {try {TimeUnit.MILLISECONDS.sle…

数据库:SQLServer中in和 exists函数用法笔记

今天给大家分享一下SQLServer中in和 exists 用法,希望能对大家有所帮助。一、IN 用法确定指定的值是否与子查询或列表中的数据相匹配。1.1 语法格式test_expression [ NOT ] IN ( subquery | expression [ ,...n ] )1.2 参数说明test_expression为任意有…

什么是m叉树_不懂数据库索引的底层原理?那是因为你心里没点b树

前几天下班回到家后正在处理一个白天没解决的bug,厕所突然传来对象的声音: 对象:xx,你有《时间简史》吗? 我:我去!妹子,你这啥癖好啊,我有时间也不会去捡屎啊&#xff01…

可重入锁是什么和demo

可重入锁 reentrantlock是独占锁且可重入的 synchronized 也可以重入 可重入意思就是这个线程已经获取锁了,你再获取该锁还能获取 获取的还是原来的锁 不会出现问题 可以降低编程难度 代码如下: new Thread(new Runnable() {Overridepublic void run() {synchr…

linux 安装python 3.x,Linux 安装python3.x步骤

本文转发自博客园非真的文章,内容略有改动linux系统本身默认安装有2.x版本的python,版本x根据不同版本系统有所不同,通过python --V 或 python --version 查看系统自带的python版本。有一些系统命令时需要用到python2,不能卸载&am…

数据库:SQLServer中游标的用法笔记

一、游标的概念知识游标可以理解为SQL Server的一种数据访问机制,它允许用户访问数据的维度是数据行。用户可以对每一行数据进行单独处理,从而降低系统开销和潜在的阻隔情况,游标主要用于存储过程,触发器和 T_SQL复杂的脚本中&…

BZOJ_1009_[HNOI2008]_GT考试_(动态规划+kmp+矩阵乘法优化+快速幂)

描述 http://www.lydsy.com/JudgeOnline/problem.php?id1009 字符串全部由0~9组成,给出一个串s,求一个长度为n的串,不包含s的种类有多少. 分析 第一眼以为是组合.然后更滑稽的是用错误的方法手算样例居然算出来是对的...我数学是有多差... 题解也是看了好半天,有点难理解. 感觉…

智慧政务解决方案(28页)pdf_【金众电子】智慧政务解决方案

智慧政务解决方案立式党建广告机广告机简介:KC-立式政务广告机(室内/室外可选)液晶屏幕特别卖点:安装简易、亮度调节、实时更新、传输安全应用场所:各种需要文化传播的政务机构、政府机关、会议场所等。双立柱政务文化栏/宣传栏文化栏简介&am…

笨办法学linux dhcp,了解网关、DNS、子网掩码、MAC地址、DHCP

原标题:了解网关、DNS、子网掩码、MAC地址、DHCP什么是网关、DNS、子网掩码,它有什么作用,确实,我们平时在网络中总是在不断的提到网关,却很少真正的去了解它。一、什么是网关1、什么是网关网关是一种充当转换重任的计…

数据库:SQLServer Stuff 函数用法笔记

今天小编给大家分享一下自己整理一下SQLServer Stuff函数用法技巧和常用示例,有需要的朋友可以学习一下。一、Stuff函数的作用1.1官方解释STUFF 函数将字符串插入到另一个字符串中。 它从第一个字符串的开始位置删除指定长度的字符;然后将第二个字符串插…

自定义注解,aop实现注解锁

多线程环境下,会出现线程不安全的问题,所以要对某些方法加锁以保证线程安全 但是如果方法过多,每个方法前后都加这么一句,有点麻烦了,而且代码可读性也会差一些。可以使用aop切面编程,对某些加有特定注解&…

手机端刷recovery工具_MIUI/REDMIN手机玩机汇集

愿你刷机半生归来仍是MIUI1解锁篇解锁Bootloader准备工作:1.手机备份数据2.手机进入开发者模式①进入“设置 -> 我的设备 -> 全部参数"中连续点击MIUI版本,进入”开发者模式“②进入“设置 -> 开发者选项 -> 设备解锁状态”中绑定账号和…

数据结构基础:线性表学习笔记

1、线性表定义线性表是指n个元素的有限序列(n>0),通常用(a1,a2,a3...,an),来表示。2、线性表特点1、存在唯一的一个首元素2、存在唯一一个尾元素3、除第首元素外,每个元素只有一个直接前驱。4、除尾元素外,每个元素只有一个直接后继。3、线性表的存储…

iphone导出照片到电脑_iPhone里的照片如何快速导入电脑

前几日我一好友发微信问我:“向阳,我手机里有一万多张照片,怎么能快速的备份到电脑里?”我一看这问题,确实很多果友从用苹果手机开始,机器已经更新换代了好多代了,照片是越来越多,内…

数据结构基础:栈和队列学习笔记

1、栈1.1 栈的定义栈是只能通过访问它的一端来实现数据的存储和检索的一种特殊的线性数据结构。栈的修改要遵循先进后出的原则,这个是栈的核心。在栈中进行插入和删除操作的一端称为栈顶(Top)。另一端被称为栈底(bottom&#xff0…

idea @Autowired 注入爆红(无法注入)

问题如下图所示,idea Autowired 注入爆红(无法注入) seettings ----> Editor Inspactions ----->spring ---->spring Core ----> Code ----> Autowring for Bean Class 去掉那个勾 效果如下

华为手机相册怎么镜像翻转_怎么利用手机相册制作电子视频

怎么通过手机照片制作视频?将照片做成视频并不是很难,可以直接在手机上进行操作,下面来看看是怎么操作的。方法/步骤在手机上打开清爽视频编辑器,有视频编辑、美拍美摄、电子相册、特效模板、动感视频、创意视频、动态字幕、视频变…

数据结构基础:树结构的学习笔记

1、树的定义树是n(n>0)个节点的有限集合。当n0时称为空树,当n>0 为非空树,任何非空树中,有且仅有一个根节点;其余节点可分为m(m>0)个互不相交的有限集合T1、T2 等,其中每一个集合都可以称为一棵树&#xff0c…