《前端之路》之 JavaScript 进阶技巧之高阶函数(下)
目录
- 第二章 - 03: 前端 进阶技巧之高阶函数 一、防篡改对象 1-1:Configurable 和 Writable
- 1-2:Enumerable
- 1-3:get 、set
- 2-1:不可扩展对象
- 2-2:密封的对象
- 2-3:冻结的对象
第二章 - 03: 前端 进阶技巧之高阶函数
一、防篡改对象
JavaScript共享的本质一直是开发人员心头的痛,因为任何对象都可以被在同一个环境中运行的代码修改。
ECMAScript5致力于解决这个问题,可以让开发人员定义
防篡改对象(tamper-proof object)。它的原理就是
通过设置每个对象的属性的一下的默认属性:
- [[Configurable]] --- 是否可配置
- [[Writable]] --- 是否可以重新赋值
- [[Enumerable]] --- 是否可列举的
- [[Value]] --- 默认值
- [[Get]]
- [[Set]]
1-1:Configurable 和 Writable
下面我们就针对以上每一个属性进行 解析一下:
// Demo one var o = {} Object.defineProperty(o, 'name', { value: 'zhang', configurable: false }) console.log(o) Object.defineProperty(o, 'name', { writable: false }) o.name = 'Li' console.log(o) // {name: 'zhange'} 属性未被改变
上面的 Demo 中 我们将 configurable 属性设置成为 false, 再对比下面的 Demo 来看 configurable 属性作用
// Demo two var o = {} Object.defineProperty(o, 'name', { value: 'zhang', configurable: false }) console.log(o) Object.defineProperty(o, 'name', { writable: true }) o.name = 'Li' // Uncaught TypeError: Cannot redefine property: name 报错
总结: 当 [[Configurable]] 为 fasle 的时候 [[Writable]] 默认已经被设置 false, 如果去修改 [[Writable]] 的时候
则会报错。 那么我们就可以理解为 当 [[Configurable]] 为 false 的时候, [[Writable]] 是只能为 false的。
1-2:Enumerable
我们还是用 Demo 来进行对比解释:
var o = {} Object.defineProperty(o, 'age', { enumerable: true, value: 18 }) for(item in o) { console.log(item, o[item]) // age 18 }
把 enumerable 设置成 false
var o = {} Object.defineProperty(o, 'age', { enumerable: false, value: 19 }) for(item in o) { console.log(item, o[item]) // undefined }
1-3:get 、set
get 和 set 这对双胞胎我们已经说过多次了。这次我们仔细来看下这个~
var o = {} var v = 'coder' Object.defineProperty(o, 'job', { get: function() { console.log('get:', v) return v }, set: function(newV) { console.log('set:', newV) v = newV } }) o.job = 'xxx' // set: xxx // 很奇怪的一点就是 当我们在 浏览器控制台点开 o 对象的时候,再次去点击 job 属性,就会触发 get 方法。
2-1:不可扩展对象
Object.preventExtensions(o)
可以使得 不能再给对象添加属性和方法
var o = {name: 'zhang'} Object.preventExtensions(o) o.age = '12' console.log(o) // {name: 'zhang'} // 已经阻止了给对象添加属性和方法了。再去添加 也未能添加上
Object.isExtensible(o)
确定对象是否可以扩展
var o = {name: 'zhang'} var res1 = Object.isExtensible(o) Object.preventExtensions(o) var res2 = Object.isExtensible(o) console.log(res1, res2) // true false
2-2:密封的对象
Object.seal(o)
密封对象不可扩展,而且已有成员的[[Configurable]]特性被设置为false,意味着不能删除属性和方法。不可增加,不能删除。
var o = {name: 'Li'} Object.isSealed(o) // false Object.seal(o) Object.isSealed(o) // true
Object.isSealed(o)
检测时候被密封了(🐝 )
2-3:冻结的对象
Object.freeze(o)
最严格的防篡改级别就是冻结对象(frozen object)。冻结的对象不能扩展,又是密封的,而且对象属性的[[Writable]]特性会被设置为false。
如果定义了[[Set]]函数,访问器属性仍然是可写的。
var obj = {age: 123} Object.freeze(obj) Object.isFrozen(obj) // true Object.isSealed(obj) // true Object.isExtensible(obj) // false
Object.isFrozen(o)
检查是否被冻结
二、自定义事件
基于
观察者模式的一种创建松散耦合代码的技术。使用自定义事件有助于解耦相关对象,保持功能的隔绝。
function EventTarget(){ this.handlers = {}; } EventTarget.prototype = { constructor : EventTraget, addHandler : function(type,handler){ if(typeof this.handlers[type] === 'undefined'){ this.handlers[type] = []; } this.handlers[type].push(handler); }, fire : function(event){ if(!event.target){ event.target = this; } if(this.handlers[type] instanceof Array){ var handlers = this.handlers[event.type]; for(var i = 0,len = handlers.length; i < len; i++){ handlers[i](event);//执行回调函数 } } }, removeHandler : function(type,handler){ if(this.handlers[type] instanceof Array){ var handlers = this.handlers[type]; for(var i = 0,len = handlers.length; i < len; i++){ if(handlers[i] === handler){ break; } } handlers.splice(i,1);//删除 } } }
总结: 以上则为高阶函数中的相关的一些场景的应用,但是这也仅仅是属于基础部分,实际的使用场景还需要大家自己灵活处理。
好了,本期这篇 blog 就先写到这里。
GitHub 地址:(欢迎 star 、欢迎推荐 : )
- JavaScript中split与join函数的进阶使用技巧
- JavaScript中split与join函数的进阶使用技巧
- javascript-函数进阶(闭包)
- 函数中this的指向问题 ——Javascript 进阶知识整理
- 使用 Dojo 的 Ajax 应用开发进阶教程,第 1 部分: JavaScript 技巧与高级特性
- JavaScript学习总结-技巧、实用函数、简洁方法、编程细节
- JavaScript性能优化技巧之函数节流
- Javascript中产生固定结果的函数优化技巧
- javascript中函数的5个高级技巧
- Dojo 的 Ajax 应用开发进阶教程:JavaScript 技巧与高级特性(一)
- JavaScript中字符替换函数String.replace()使用技巧
- javascript中函数的5个高级技巧 推荐
- javascript入门·向函数传递表单数据和元素(赠送一小技巧)
- javascript进阶之对象篇(3)函数与自定义”类“
- JavaScript写作技巧,函数A中调用函数B, 怎样在函数B中写代码中断函数A的运行?
- JavaScript-编程技巧-惰性载入函数
- JavaScript 性能优化技巧:函数节流
- 《Web 前端面试指南》2、JavaScript 的 Bind 函数进阶
- JavaScript进阶(一)抽离公共函数