学JS的心路历程-物件与原型(三)
昨天有说明到函式与建构式的原型,及指定建构式函式原型为另一个建构式函式,但其实这会造成复写constructor的问题。
复写constructor的问题(vmwork)
我们昨天有提到「建构式函式可以透过.constructor来存取建立物件的函式以此来作类型检查。」,但是这个例子却会导致trickyMan的建构式的原型被复写,无法去判断。
function Person(){};
Person.prototype.say =“Hi”;
function trickyMan(){};
trickyMan.prototype = new Person();
var Jason = new trickyMan();
trickyMan.constructor === trickyMan;//false
所以如果在Jason物件上呼叫.constructor,会无法找到直到在Person上找到参照Person函式的constructor。
但是,这事实上是错误的,如果我问是哪个函式建立了Jason物件,会得到Person这可能会产生一些Bug。
幸好在JS中,物件的每个属性都有一个属性描述子(property desciptor),可以够过它设定以下键值:
configurable设定
true -表属性描述子可被修改及删除
false -上述两个动作都将被禁止
enumerable列举
true -属性能在物件的for-in循环操作中出现
value
设定属性的键值
writable写入
true -表可以透过设值叙述来修改属性值
get
定义取值(getter)函式,可用来取得属性值。无法与value及writable一起设定
set
定义设值(setter)函式,可以用来对属性指派一个值。无法与value及writable一起设定
先来个简单的例子:
Jason.age = 29;
age这个属性会是可设定、可列举并且可写入的,它的值被设为29,get和set函式则会是undefined。
如果要对上述设定值做更动的话,可以用Object.defineProperty:
var Jason = {};
Jason.say =“R~”;
Object.defineProperty(Jason,“age”,{
configurable:false,
enumerable:false,
value:29,
writable:true
});
console.log(“age”in Jason);
for(let key in Jason){
console.log(key);
}
好,现在我知道有这东西了,但这跟一开始说的constructor有关系吗?
当然有!我们试着用trickyMan扩展(extend)Person时(也可以说是让trickyMan成为Person的子类别),就失去原本保存在constructor属性上的trickyMan原型。
我们可以用Object.defineProperty在新的trickyMan.prototype上定义一个新的constructor属性。
function Person(){};
Person.prototype.say =“Hi”;
function trickyMan(){};
trickyMan.prototype = new Person();
Object.defineProperty(trickyMan,“constructor”,{
enumerable:false,
value:trickyMan,
writable:true
});
var Jason = new trickyMan();
trickyMan.constructor === trickyMan;//true
那么,今天就到这边,一样如果有错误及来源未附上也欢迎留言指正,那么我们明天见(leafor)。
学JS的心路历程-物件与原型(三)的更多相关文章
- 学JS的心路历程 -物件与原型(二)
昨天有提到说Object.setPrototypeOf可以指定一个物件为另一个物件的原型,但有想过到底这个原型,也就是[[Prototype]]最终会到何处吗? 答案是Object.prototype ...
- 学JS的心路历程-物件与原型(一)
前两天说明面向对象的三大特性及JS不符合面向对象,只能称作支持面向对象而已,今天我们来看看JS的原型继承. 首先我们先来看,什么是原型(vmwork): 两个物件之间的原型关系(prototype r ...
- 学JS的心路历程 -函式(三)this
this是什么,取决于被呼叫的呼叫地点. 昨天有提到说,呼叫函式时候会传递隐含参数:arguments和this并讲解了arguments,今天我们就来探讨this吧! 什么是this 我们都会呼叫函 ...
- 学JS的心路历程 - PixiJS -基础(三)
今天我们来试着移动图片吧! 首先,一样先把图片放到PIXI的stage中: let app = new PIXI.Application({ width: 800, height: 600, back ...
- 学JS的心路历程 - JS的Class
没错,你没有看错,虽然前面说JS是原型继承,但在ES6以后新增了class关键字!!! 不过底层实作仍然是以原型继承方式进行,所以基本上算是一个语法糖. 今天我们就来看一下如何使用吧! class 首 ...
- 学JS的心路历程-JS支持面向对象?(二)
昨天讲了面向对象的继承,今天我们来谈谈多态和封装吧! 多态polymorphism 抽象讲法解释,就是使用单一界面操作多种型态的物件 继承父类别,定义与父类别中相同的方法,但实作内容不同,称为复写(o ...
- 学JS的心路历程-JS支持面向对象?(一)
昨天在看Prototype看到JS支持面向对象,被前辈问到说那什么是面向对象?JS是面向对象语言吗? 便开始了一连串艰辛爬文过程,今天就来看一下两者有什么差异吧(rgwyjc)! 首先面向对象有三大特 ...
- 学JS的心路历程-for of和for in
我们在刚入门JS时候,说到要跑出数组的每个值肯定都是这样子: var arr = [1,2,3,4,5,6]: for(let i = 0:i < arr.length:i++){ consol ...
- 学JS的心路历程Day26 - PixiJS -入坑
后来知道也可以透过canvas让网页动起来! 而PixiJS是使用WebGL在canvas上绘制内容与制作动态 且同时有下列特色: 支持多点触控 掩码与混合模式 可外加WebGL滤镜 多装置支持 等等 ...
随机推荐
- Java程序---多数字求和
题目: 编写一个程序,此程序从命令行接收多个数字,求和之后输出结果. 设计思想: 1.记录要输入的数字的个数n 2.建立一个长度为n的数组存储输入的数字 3.累加求和并输出结果 注:此程序中应用了Sc ...
- hive lateral view 与 explode详解
ref:https://blog.csdn.net/bitcarmanlee/article/details/51926530 1.explode hive wiki对于expolde的解释如下: e ...
- 在mvc中动态加载菜单
最近做了一个项目, 要在客户端动态的显示菜单,也就是这些菜单是保存在数据库中的, 在客户端动态加载菜单,这样做的好处很明显,就是菜单很容易修改,直接在后台进行维护,再也不会直接在前面的 视图页面中进行 ...
- 安全测试8_Web安全实战2(暴力破解)
1.暴力破解的概念 顾名思义,暴力破解的原理就是使用攻击者自己的用户名和密码字典,一个一个去枚举,尝试是否能够登录.因为理论上来说,只要字典足够庞大,枚举总是能够成功的! 2.暴力破解的实战 在有了之 ...
- VMware扩展Linux根目录磁盘空间(Centos版本)
1.Centos 关机,选择编辑虚拟机设置,硬盘,在实用工具那里选择“扩展”,指定你需要的存储大小 2.启动客户机操作系统Centos,查看磁盘情况 输入指令 fdisk -l 显示结果如下 Disk ...
- Android 自定义TabHost,TabWidget样式
界面比较简单,要想做得漂亮换几张图片就可以了. 第一步:先在布局(这里用了main.xml创建时自动生成的)里面放上TabHost ,只要将TabHost控件托至屏幕中就可: <?xml ver ...
- 34.纯 CSS 创作在文本前后穿梭的边框
原文地址: https://segmentfault.com/a/1190000015045700 感想: 动画 + z-index:n ; HTML code: <div class= ...
- Python基础7 面向对象编程进阶
本节内容: 面向对象高级语法部分 经典类vs新式类 静态方法.类方法.属性方法 类的特殊方法 反射 异常处理 Socket开发基础 作业:开发一个支持多用户在线的FTP程序 面向对象高级语法部分 经典 ...
- 四、Java web 部 分试题
1 .Tomcat 的 优 化 经 验 答:去掉对 web.xml 的监视,把 jsp 提前编辑成 Servlet. 有富余物理内存的情况,加大 tomcat 使用的 jvm 的内存 2 .HTTP ...
- 异常+远程控制Linux-14
什么是异常 a=8950/0 ZeroDivisioonError: division by zero print (a) ************** b = [1,2] ...