《JS权威指南学习总结--6.7属性的特性》

内容要点:

一.ES5中查询和设置属性的API

      1.可以通过这些API给原型对象添加方法,并将它们设置成不可枚举的,这让它们看起来更像内置方法。

      2.可以通过这些API给对象定义不能修改或删除的属性,借此 "锁定" 这个对象。

      3.数据属性的4个特性: 值(value)、可写性(writable)、可枚举性(enumerable)和可配置性(configurable)。

      4.存取器属性不具有值特性和可写性,它们的可写性是由setter方法存在与否决定的。因此存取器属性的4个特性是:读取(get)、写入(set)、可枚举性(numberable)和可配置性(configurable)。

      其中writable、enumerable和configurable都是布尔值,当然,get属性和set属性是函数值。

二.Object.getOwnPropertyDescriptor()

      1.通过调用Object.getOwnPropertyDescriptor()可以获得某个对象特定属性的属性描述符:

      例如:

         //返回{ value : 1,writable : true,enumerable:true,configurable:true }

         Object.getOwnPropertyDescriptor({x:1},"x");

        //查询上文中定义的random对象的octet属性

        //返回{get:/*func*/,set:undefined,enumerable:true,configurable:true}

       Object.getOwmPropertyDescriptor(random,"octet");

       //对于继承属性和不存在的属性,返回undefined

        Object.getOwnPropertyDescriptor({},"x"); //undefined,没有这个属性

        Object.getOwnPropertyDescriptor({},"toString"); //undefined,继承属性

        Object.getOwnPropertyDescriptor()只能得到自有属性的描述符。要想获得继承属性的特性,需要遍历原型链

三.Object.definePeoperty()

       传入要修改的对象,要创建或修改的属性的名称以及属性描述符对象。

       var o = {}; //创建一个空对象

       //添加一个不可枚举的数据属性x,并赋值为1

        Object.defineProperty(o,"x",{value:1,writable:true,enumerable:false,configurable:true});

      //属性是存在的,但不可枚举

        o.x; //=>1

         Object.keys(o) //=>[]

      //现在对属性x做修改,让它变为只读

        Object.defineProperty(o,"x",{writable:false});

     //试图更改这个属性的值

       o.x = 2; //操作失败但不报错,而在严格模式中抛出类型错误异常

       o.x=1;

      //属性依然是可配置的,因此可以通过这种方式对它进行修改

        Object.defineProperty(o,"x",{value:2});

        o.x //=>2

      //现在将x从数据属性修改为存取器属性

       Object.defineProperty(o,"x",{get:function(){return 0;}});

       o.x //=>0

      传入Object.defineProperty()的属性描述符对象不必包含所有4个特性。对于新创建的属性来说,默认的特性值是false或undefined。对于修改的已有属性来说,默认的特性值没有做任何修改。注意:这个方法要么修改已有属性要么新建自有属性,但不能修改继承属性。

四.Object.defineProperties()

       同时修改或创建多个属性。第一个参数是要修改的对象,第二个参数是一个映射表,它包含要新建或修改的属性的名称,以及它们的属性描述符

       例如:

       var p = Object.defineProperties({},{

              x:{value:1,writable:true,enumerable:true,configurable:true},

              y:{value:1,writable:true,enumerable:true,configurable:true},

              r:{  

                    get:function(){ return Math.sqrt(this.x*this.x+this.y*this.y) },

                     enumerable:true,

                     configurable:true

                  }

         });

         这段代码从一个空对象开始,然后给它添加了两个数据属性和一个只读存储器属性,最终Object.defineProperties()返回修改后的对象

五.

      对于那些不允许创建或修改的属性来说,如果用Object.defineProperty()和Object.defineProperties()返回修改后的对象(新建或修改)就会抛出类型错误异常,

      比如,给一个不可扩展的对象新增属性就会抛出类型错误异常。造成这些方法抛出类型错误异常的其他原因则和特性本身相关。

      可写性控制着特性的修改,可配置性控制着对其他特性的(包括属性是否可以删除)的修改。然而规则远不止这么简单:

      例如,如果属性是可配置的话,则可以修改不可写属性的值。同样,如果属性是不可配置的,仍然可以将可写属性修改为不可写属性。

      下面是完整的规则,任何对Object.defineProperty()或Object.defineProperties()违反规则的使用都会抛出类型错误异常

            1.如果对象是不可扩展的,则可以编辑已有的自有属性,但不能给它添加新属性

            2.如果属性是不可配置的,则不能修改它的可配置性和可枚举性。

            3.如果存取器属性是不可配置的,则不能修改其getter和setter方法,也不能将它转换为数据属性

            4.如果数据属性是不可配置的,则不能将它转换为存取器属性

            5.如果数据属性是不可配置的,则不能将它的可写性从false修改为true,但可以从true修改为false。

            6.如果数据属性是不可配置的且不可写的,则不能修改它的值。然而可配置但不可写属性的值是可以修改的(实际上是先将它标记为可写的,然后修改它的值,最后转换为不可写的)

六.

    上节中实现了extend()函数,这个函数把一个对象的属性复制到另一个对象中。这个函数只是简单地复制属性名和值,没有复制属性的特性,而且也没有复制存取器属性的getter和setter方法,只是将它们简单地转换为静态的数据属性。

     下例给出了改进的extend(),它使用Object.getOwnPropertyDescriptor()和Object.defineProperty()对属性的所有特性进行复制。新的extend()作为不可枚举属性添加到Object.prototype中,因此它是Object上定义的新方法,而不是独立的函数。

      /*给Object.prototype添加一个不可枚举的extend()方法 

       *这个方法继承自调用它的对象,将作为参数传入的对象的属性一一复制

       *除了值之外,也复制属性的所有特性,除非在目标对象中存在同名的属性

       *参数对象的所有自有对象(包括不可枚举的属性)也会一一复制      

       */    

       Object.defineProperty(Object.prototype,

          "extend",

          {

              writable: true,

              enumerable:false,              //将其定义为不可枚举的

              configurable:true,

              value:function(o){            //值就是这个函数

                    //得到所有的自有属性,包括不可枚举属性

                    var names = Object.getOwnPropertyNames(o);

                    //遍历它们

                    for(var i = 0; i <names.length; i++){

                          //如果属性已经存在,则跳过

                          if(names[i] in this) continue;

                         //获得o中的属性的描述符

                         var desc = Object.getOwnPropertyDescriptor(o,names[i]);

                         //用它给this创建一个属性

                         Object.defineProperty(this,names[i],desc);

                  }

              }

       });

 

转载于:https://www.cnblogs.com/hanxuming/p/5795441.html

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

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

相关文章

【干货分享】流程DEMO-事务呈批表

流程名&#xff1a; 事务呈批表 业务描述&#xff1a; 办公采购、会议费用等事务的申请。流程发起时&#xff0c;会检查预算&#xff0c;如果预算不够&#xff0c;将不允许发起费用申请&#xff0c;如果预算够用&#xff0c;将发起流程&#xff0c;同时占用相应金额的预算&…

【译】TcMalloc: Thread-Caching Malloc

TcMalloc 的核心是分层缓存&#xff0c;前端没有锁竞争&#xff0c;可以快速分配和释放较小的内存对象&#xff08;一般是 256 KB&#xff09;前端有两种实现&#xff0c;分别是 pre-CPU 和 pre-Thread 模式&#xff0c;前者申请一块大的连续内存&#xff0c;每一个逻辑 CPU 将…

kotlin编译失败_Kotlin使用GraalVM开发原生命令行应用

背景之前用kotlin开发过一款根据建表DDL语句生成plantuml ER图的应用。被问如何使用&#xff0c;答曰"给你一个jar包&#xff0c;然后执行java -jar ddl2plantuml.jar ./ddl.sql ./er.puml 就可以了。是不是so easy?"结果被吐槽了一番&#xff0c;为什么不能像命令行…

Swift - 添加纯净的Alamofire

Swift - 添加纯净的Alamofire 如果你有代码洁癖,不能容忍任何多余的东西,请继续往下看. 1. 下载Alamofire (https://github.com/Alamofire/Alamofire) 2. 解压缩并打开 Alamofire.xcworkspace 3. 删除不必要的内容 (根据你的需求自己定) 4. 顺便把文件夹里面的无关内容也删除掉…

jquery 获取系统默认年份_你没有看错,爬网页数据,C# 也可以像 Jquery 那样

一&#xff1a;背景1. 讲故事前段时间搞了一个地方性民生资讯号&#xff0c;资讯嘛&#xff0c;都是我抄你的&#xff0c;你抄官媒的&#xff0c;小市民都喜欢奇闻异事&#xff0c;所以就存在一个需求&#xff0c;如何去定向抓取奇闻异事的地方号上的新闻&#xff0c;其实做起来…

linux下怎么编译运行C语言程序?

linux下的C语言编译器是gcc&#xff0c;C的编译器是g。 linux下编程可以使用编辑器vi或vim&#xff0c;建议使用vim&#xff0c;因为它有语法高亮显示。程序编写好后&#xff0c;假设你的程序名为test.c&#xff0c;可以使用gcc -o test test.c。test就是编译好的可执行程序./t…

undertow 怎么创建线程_为什么很多SpringBoot开发者放弃了Tomcat,选择了Undertow

点击上方“后端技术精选”&#xff0c;选择“置顶公众号”技术文章第一时间送达&#xff01;作者&#xff1a;阿迈达toutiao.com/a6775476659416990212/前言在SpringBoot框架中&#xff0c;我们使用最多的是Tomcat&#xff0c;这是SpringBoot默认的容器技术&#xff0c;而且是内…

一起玩转CoordinatorLayout

作为Material Design风格的重要组件,CoordinatorLayout协调多种组件的联动&#xff0c;实现各种复杂的效果&#xff0c;在实际项目中扮演着越来越重要的角色。本篇博客将由浅到深&#xff0c;带你一起玩转CoordinatorLayout。 官方文档对CoordinatorLayout是这样描述的&#xf…

离散数学图论旅行规划问题_2020年MathorCup高校数学建模挑战赛——C 题 仓内拣货优化问题...

下面的链接是精华版思路&#xff0c;亮点是对第六问的探讨。高度概括一下&#xff1a;第一问曼哈顿&#xff0c;第二问用免疫&#xff0c;三问增加任务单&#xff0c;四问增加拣货员&#xff0c;五问改变复核台&#xff0c;六问亮点来探讨~ 有点皮MathorCup C题 仓内拣货优化问…

Asp.NetWebForm的控件属性

一&#xff1a;GridView&#xff1a; 1.绑定ID 的值&#xff1a;DataKeyNames"Id", 2.自动产生列的意思:AutoGenerateColumns 3.如何注册脚本&#xff1a;ClientScript.RegisterStartupScript(this.GetType(),"text","alert(删除成功)"&#xf…

【VBA编程】10.自定义集合

自定义集合类型&#xff0c;类似于变量声明&#xff0c;只是要将Dim关键字和New collection关键字搭配起来使用&#xff0c;其语法描述如下&#xff1a;其中集合名的命名方式同于标准变量的命名 Dim 集合名 As New collection 对于已经定义的集合对象&#xff0c;可以使用集合的…

git fork clone 区别_Working with Git | Git 与 GitHub

关于各位好&#xff0c;这里是 Chinas Prices Project 项目的知乎专栏。关于 CPP 项目&#xff0c;您可以在这篇文章里了解到更多的信息。若您对这个项目感兴趣&#xff0c;我们非常欢迎您与我们交流您的想法与见解。在一个团队的成员同时为一个项目进行开发工作时&#xff0c;…

舒适的路线(codevs 1001)

题目描述 DescriptionZ小镇是一个景色宜人的地方&#xff0c;吸引来自各地的观光客来此旅游观光。Z小镇附近共有N(1<N≤500)个景点&#xff08;编号为1,2,3,…,N&#xff09;&#xff0c;这些景点被M&#xff08;0<M≤5000&#xff09;条道路连接着&#xff0c;所有道路都…

PHP_Smarty

模板 数据与表现层的标签分离 smarty是PHP 与 HTML代码的分离 小型模板类 $smarty 的工作流程&#xff1a; 把需要显示的全局变量&#xff0c;赋值塞到对象内部的属性上&#xff0c;一个数组中.编译模板&#xff0c;把{$标签},解析成相应的<?php echo 代码引入编译后的PHP文…

读中文_挑战来了!康辉喊你读中文十级绕口令!

文章来源&#xff1a;央视频汉语桥木甬读桶不读涌&#xff0c;月农读脓不读胧。米更读粳不读梗&#xff0c;日青读晴不读睛。米宗读粽不读综&#xff0c;言丁读订不读钉。土竟读境不是镜&#xff0c;土平读坪不是评。耳令读聆不读岭&#xff0c;火登读灯不读澄。言甬读诵不读蛹…

ios 自定义键盘

由于项目需要&#xff0c;需要自定义键盘。ios系统键盘会缓存键盘输入&#xff0c;并保存在系统目录下的文件里&#xff0c;并且是明文存储&#xff0c;存在帐号密码泄漏风险。在别人代码基础上修改了下&#xff0c;美化了下界面&#xff0c;去掉了字符输入&#xff0c;加了点击…

对象入参指定泛型类型_为什么要使用泛型,而不是直接将类型作为参数传递?

其实很多类型系统都是用类型参数的的形式来实现Universal Type的&#xff0c;Parametric Polymorphism 和System F可以了解一下&#xff0c;如果只局限于一两个热门语言的话&#xff0c;可能会有此疑问&#xff0c;但是从type theory的角度来说&#xff0c;高阶类型本身就是typ…

【GOF23设计模式】迭代器模式

【GOF23设计模式】迭代器模式 来源&#xff1a;http://www.bjsxt.com/ 一、【GOF23设计模式】_迭代器模式、JDK内置迭代器、内部类迭代器 1 package com.test.iterator;2 /**3 * 自定义的迭代器接口4 */5 public interface MyIterator {6 void first(); //将游标指向第…

SQLServer 维护脚本分享(08)临时数据库(tempdb)

dbcc sqlperf(logspace) --各数据库日志大小及使用百分比dbcc loginfo --查看当前数据库的虚拟日志文件--临时表Tempdb最近使用情况 SELECT t1.session_id ,t1.internal_objects_alloc_page_count*8.0/1024 as internal_objects_alloc_MB ,t1.internal_objects_dealloc_p…

51单片机50个实例代码_【附代码】51单片机电子密码锁教程

简介大家好&#xff0c;这篇文章的内容是关于如何用51单片机来制作一个电子密码锁的教程&#xff0c;通过这篇教程可以让刚入门的朋友了解矩阵键盘、LCD1602的使用方法&#xff0c;以及密码输入和修改的程序介绍&#xff0c;我会对每个部分进行详细的介绍。首先我们来看一下这个…