const定义的常量,一般是不能修改的。

比如:

 const TIME_OUT = 10000;

但是当值为引用类型值时,还是可以操作对象,扩展或修改对象属性、方法等等。

以下演示代码的操作是不会报错,且行之有效的。。

 const person = {
name: 'xm'
}
person.age = 18;
person.name = 'xh';

ES6(?)在Object上添加了一个静态方法freeze() ,可以禁止修改、扩展引用类型值。

用法就是把person作为参数传入该方法中。如:

 const person = {
name: 'xm'
}
console.log(person);// {name: 'xm'};
Object.freeze(person);
person.age = 18;
person.name = 'xh';
console.log(person);// {name: 'xm'};

好厉害,这下子就成了名副其实的常量了。emm....

freeze方法实现原理的简单模拟

要使用的到方法包括Object.definedProperty()、Object.seal()

Object.definedProperty()方法可以定义对象的属性的特性。如可不可以删除、可不可以修改、访问这个属性的时候添油加醋等等。。

用法(详见高级程序设计P139):

 Object.defineProperty(person, 'name', {
configurable: false,// 表示能否通过delete删除属性,能否修改属性的特性...
enumerable: false,// 表示是否可以枚举。直接在对象上定义的属性,基本默认true
writable: false,// 表示能否修改属性的值。直接在对象上定义的属性,基本默认true
value: 'xm'// 表示属性的值。访问属性时从这里读取,修改属性时,也保存在这里。
})

通过以上代码的设置,name属性就变成了不能删除、不可重新修改特性、不可枚举、不能修改的属性值的属性了。

测试结果:

非常重要的一个方法。以上就是它的简单用法以及实现效果。

Object.seal()方法可以让对象不能被扩展、删除属性等等。用法:Object.seal(person);

有了这两个方法,就可以实现一个简单的freeze()方法了。代码演示:

 function myFreeze(obj) {
if (obj instanceof Object) {
Object.seal(obj);
let p;
for (p in obj) {
if (obj.hasOwnProperty(p)) {
Object.defineProperty(obj, p, {
writable: false
});
myFreeze(obj[p]);// 递归,实现更深层次的冻结
}
}
}
}

以上函数先判断传入参数是否为Object类型。为真,接着封闭对象。for in 循环遍历对象。

剔除原型属性,设置属性的writable特性为false。递归调用该函数,传入属性值。

测试结果:

学习完一个。再接再厉。

来实现一下instanceof 操作符吧

instanceof的大致效果是:当左边是基本类型值时,一律返回false。 当左边是引用类型值时,如果右边的原型对象,在左边的原型链上存在,返回真,否则假。

有了大概的使用效果,加上一些方法。就可以实现一个简单的instanceof操作符了。代码演示:

 function myInstanceof(leftVal, rightFunc) {
if (typeof rightFunc !== 'function') throw new Error('第二个参数请传入构造函数名');
return rightFunc.prototype.isPrototypeOf(leftVal);
// F.prototype.isPrototypeOf(obj)判断obj的原型指针是否指向传入构造函数的原型对象,这个过程会往上层层判断。
// 比如,以下验证myInstanceof(xm, Object);xm的原型指针指向Person.prototype,Person.prototype的原型指针指向Object.prototype。所以返回true。 4 }

验证结果:

其他一些实现方法:

 function myInstanceof(leftVal, rightFunc) {
if (typeof rightFunc !== 'function') throw new Error('第二个参数请传入构造函数名');
if (typeof leftVal !== 'object' || leftVal === null) return false;
if (leftVal.__proto__ === rightFunc.prototype) {// __proto__原型指针
return true;
} else {
return myInstanceof(leftVal.__proto__, rightFunc);
}
}

以上利用浏览器在对象上布置的__proto__属性、加递归调用实现判断。

 function myInstanceof(leftVal, rightFunc) {
if (typeof rightFunc !== 'function') throw new Error('第二个参数请传入构造函数名');
if (typeof leftVal !== 'object' || leftVal === null) return false;
let _proto = Object.getPrototypeOf(leftVal);
while (_proto) {
if (_proto === rightFunc.prototype) {
return true;
}
_proto = Object.getPrototypeOf(_proto);
}
return false;
}

以上利用Object.getPrototypeOf()方法获取对象的原型,利用while循环层层递进。都没有,最后Object.getPrototypeOf()值为null。

JavaScript内置一些方法的实现原理--Object.freeze()、instanceof的更多相关文章

  1. JavaScript内置一些方法的实现原理--new关键字,call/apply/bind方法--实现

    先学习下new操作符吧 new关键字调用函数的心路历程: 1.创建一个新对象 2.将函数的作用域赋给新对象(this就指向这个对象) 3.执行函数中的代码 4.返回这个对象 根据这个的思路,来实现一个 ...

  2. JavaScript内置一些方法的实现原理--new关键字,call/apply/bind方法--前戏

    new关键字,call/apply/bind方法都和this的绑定有关,在学习之前,首先要理解this. 一起来学习一下this吧 首先.this是一个对象. 对象很好理解,引用类型值,可以实现如th ...

  3. 【废弃中】JavaScript 内置Object

    创建: 2017/09/24 更新: 2018/01/22 增加window对象内容的链接 更改标题: [JavaScript 主要的自带Object] -> [JavaScript 内置Obj ...

  4. JVM源码分析之深入分析Object类finalize()方法的实现原理

      原创申明:本文由公众号[猿灯塔]原创,转载请说明出处标注 ​“365篇原创计划”第十篇. 今天呢!灯塔君跟大家讲: 深入分析Object类finalize()方法的实现原理 finalize 如果 ...

  5. Atitit paip.对象方法的实现原理与本质.txt

    Atitit paip.对象方法的实现原理与本质.txt 对象方法是如何实现的1 数组,对象,字典1 对象方法是如何实现的 这显然是一个对象方法调用.但对象方法是如何实现的呢?在静态语言中,因为有编译 ...

  6. JavaScript 内置函数有什么?

    javaScript内置函数 1.Date:日期函数 属性:constructor 所修立对象的函数参考prototype 能够为对象加进的属性和方法 方法:getDay() 返回一周中的第几天(0- ...

  7. 第7天-javascript内置对象

    数组相关方法 concat 用来连接多个数组 <script> var a = [1,2,3]; var b = [3,4,5]; var c = a.concat(b); console ...

  8. javascript 内置对象及常见API

    javascript 内置对象及常见API 2012-09-02 15:17 571人阅读 评论(0) 收藏 举报 javascript正则表达式文档浏览器urlstring Javascript内置 ...

  9. JavaScript进阶 - 第7章 JavaScript内置对象

    第7章 JavaScript内置对象 7-1 什么是对象 JavaScript 中的所有事物都是对象,如:字符串.数值.数组.函数等,每个对象带有属性和方法. 对象的属性:反映该对象某些特定的性质的, ...

随机推荐

  1. VAE论文学习

    intractable棘手的,难处理的  posterior distributions后验分布 directed probabilistic有向概率 approximate inference近似推 ...

  2. Spring cloud微服务安全实战-3-6API安全机制之数据校验

    校验:非空.唯一性等校验 密码的加密:密码加密来存储. 如何做https的访问 校验 一个层面是接口层面,另外一个层面是数据库层面. Springboot给我们提供了简单的封装 校验的包里面还有其他的 ...

  3. xshell连接中标麒麟

    中标麒麟: 1.首先肯定需要给虚拟机配置静态ip,让虚拟机作为独立的ip存在 https://www.cnblogs.com/judes/p/11776872.html 2.输入rpm -qa | g ...

  4. 【微信开发】微信小程序通过经纬度计算两地距离php代码实现

    需求: 要求做个根据用户当前位置获取周围商家地址,并且按照由近到远排序, 方法一: 代码层实现 封装方法: /** * @desc 根据两点间的经纬度计算距离 * @param float $lat ...

  5. C#关于时间(获取特定格式的时间及多种方式获取当前时间戳)以及10位和13位时间戳转为特定格式

    C#关于时间(获取特定格式的时间及多种方式获取当前时间戳)以及10位和13位时间戳转为特定格式 置顶 2018年03月06日 19:16:51 黎筱曦 阅读数:19098 标签: C#时间 更多 个人 ...

  6. Laya的屏幕适配,UI组件适配

    参考: 屏幕适配API概述 版本2.1.1.1 目录 一 适配模式 二 UI组件适配 一 适配模式 基本和白鹭的适配模式一样. Laya官方也推荐了竖屏使用fiexedwidth,横屏使用fixedh ...

  7. 对ThreadLocal的理解

      参考文档:https://www.cnblogs.com/moonandstar08/p/4912673.html   一.定义:线程本地变量,每个线程中的变量相互独立,互不影响. 官方定义: 1 ...

  8. ACS712电流传感器应用

    1. 原理图 其中第7脚输出的是电压值,那么电压值和测量的电流什么关系?看下图,有3个量程,我用的是20A电流的,100mv电压对应1A电流 看下图,不同的温度会有影响,不过区别不大 最后计算的公式是 ...

  9. selenium3+Python3+sublime text3自动化登录

    前言: 对于初学者来说,python自带的IDLE,精简又方便,不过一个好的编辑器能让python编码变得更方便,更加优美些. 不过呢,也可以自己去下载其他更好用的代码编辑器,在这推荐: PyChar ...

  10. gcr 镜像无法下载问题

    GCR Proxy Cache 帮助 GCR Proxy Cache服务器相当于一台GCR镜像服务器,国内用户可以经由该服务器从gcr.io下载镜像. 使用GCR Proxy Cache从gcr.io ...