前端进阶JS函数增强与对象增强
JS函数增强
函数属性
JavaScript中函数也是一个对象,那么对象中就可以有属性和方法,他有一些默认的属性
- name 函数名
- length 函数参数个数(ES6
...
语法不会被算在内) - arguments 类似数组对象 可以i用索引来获取对象
- rset
PS: 箭头函数不绑定 Arguments 对象
arguments 转为数组对象常见方法
普通的方法 就是将内容一个一个迭代到新数组了
let newArray = []// argumentsfunction foo1(m, n) {for (var arg of arguments) {newArray.push(arg)}// arguments类似数组的对象(它可以通过索引来获得对象)console.log(newArray)}foo1(1, 2)
ES6 中的方法
- Array.form() 传入一个可迭代对象就可以转为数组
- 对象结构
...
的方式来复制
// 方法2var newArray1 = Array.from(arguments)// 方法3var newArray = [...arguments]
rset
如果最后一个参数是 … 为前缀的,那么它会将剩余的参数放到该参数中,并且作为一个数组
function foo1(m, n, ...arg)
- arguments 对象包含了传给函数的所有实参但是不是数组对象 需要转换
- rest参数是一个真正的数组,可以进行数组的所有操作
- arguments是早期为了方便去获取所有的参数提供的数据结构,rest参数是ES6中提供并且希望替代arguments的方案
纯函数理解和应用
副作用:
执行函数时,除了返回函数值之外,还对调用函数产生了附加的影响,比如修改了全局变量,修改参数或者改变外部的存储
纯函数的理解
- 输入 相同值的时候产生同样的输出 所以纯函数不能通过闭包的特性调用上层属性,因为会随着上层属性变化函数输出内容
- 函数的输出和输入值以外的信息无关和设备的外部输出也无关
- 这个函数不能有语义上可观察到的 “副作用”
纯函数辨别案例
- slice:slice截取数组时不会对原数组进行任何操作,而是生成一个新的数组
- splice:splice截取数组, 会返回一个新的数组, 也会对原数组进行修改
var names = ["abc", "nba", "nbc", "cbd"]var newNames = names.slice(0, 2)var newNames1 = names.splice(0, 2)console.log(newNames);console.log(newNames1);
纯函数的优势
- 稳定,可以放心使用
- 保证函数的纯度 简单的实现自己的业务逻辑,和外置的各种因素依赖关系少
- 用的时候需要保证输入的内容不被任意篡改,并且需要确定输入一定会有确定的输出
柯里化的理解和应用
函数式编程重要概念,他是一个作用于函数的高阶技术,在其他的编程语言也有使用
只传递函数部分参数来调用,让它返回一个函数去处理剩余的参数这个过程就被成为柯里化
// 普通的函数function foo(x, y, z) {console.log(x + y + z);}foo(10, 20, 30)// 柯里化的结果function kelifoo(x) {return function (y) {return function (z) {console.log(x + y + z);}}}kelifoo(10)(20)(30)//箭头函数写法var foo2 = x => y => z => { console.log(x + y + z) }
自动柯里化函数
// 需要转化的例子function sum(num1, num2) {console.log(num1 + num2);return num1 + num2}// 自动柯里化函数function hyCurrying(fn) {// 1 继续返回一个新的函数 继续接受函数// 2 直接执行 fn 函数function curryFun(...args) {if (args.length >= fn.length) {// 执行第二种操作return fn.apply(this, args)} else {return function (...newArgs) {return curryFun.apply(this, args.concat(newArgs))}}}return curryFun}// 对其他函数柯里化var sumCurry = hyCurrying(sum)sumCurry(10)(5)sumCurry(10, 5)
柯里化函数只有在某些特殊的场景才需要使用。他得性能并不高也可能引起闭包的内存泄漏所以使用的时候需要注意。
组合函数理解和应用
当我们需要嵌套调用两个函数的时候,为了方便复用,我们可以写一个组合函数
var sum = pow(double(12))
我们可以编写一个通用的组合函数来让我们使用组合函数更加的便捷,其实思路就是很简单的将函数放入数组判断边界顺序执行
function sum(num) {return num * 2}function pow(num) {return num ** 2}function composeFn(...fns) {// 边界判断var length = fns.lengthif (length < 0) {return}for (let i = 0; i < length; i++) {var fn = fns[i]if (typeof fn != "function") {throw new Error(`index postion ${i} must be function`)}}//轮流执行函数 返回结果对象return function (...args) {var result = fns[0].apply(this, args)for (let i = 1; i < length; i++) {var fn = fns[i]result = fn.apply(this, [result])}return result}}var newfn = composeFn(sum, pow)console.log(newfn(5)); //100
with语句、eval函数(拓展知识)
with
语句 扩展一个语句的作用域链,不推荐使用有兼容性问题
eval
允许执行一个代码字符串。他是一个特殊函数可以将传入的字符串当作js代码执行
- 可读性差
- 有注入风险
- 必须经过解释器 不会得到引擎的优化
严格模式的使用
js的局限性 :
- JavaScript 不断向前发展且并未带来任何兼容性问题;
- 新旧代码该新模式对于向下兼容有帮助但是也有问题出现
- 就是创造者对于js的不完善之处会一直保留
ES5标准中提出了严格模式的概念,以更加严格的方式对代码进行检测和执行
只需要在代码的开头或者函数的开头 加入use strict
就可以开启严格模式
JS对象增强
数据属性描述符
我们的属性一般定义在对象的内部或者直接添加到对象内部,但是这种方式我们就不能对属性进行一些限制,比如这个属性是否是可以通过delete删除,是否可以for-in遍历的时候被遍历出来等等
PS: 一个属性进行比较精准的操作控制,就可以使用属性描述符。
- 通过属性描述符可以精准的添加或修改对象的属性
- Object.defineProperty 来对属性进行添加或者修改
这个方法会直接在一个对象上定义一个新属性,或者修改一个对象的现有属性,并返回此对象
Object.defineProperty()
属性描述符分类
分为两类:
- 数据属性
- 存取属性
数据属性描述符
Configurable
:表示属性是否可以通过delete删除属性,是否可以修改它的特性
- 使用对象定义属性的时候为true
- 使用属性描述符来定义的时候 默认为false
Enumerable
:表示属性是否可以通过for-in或者Object.keys()返回该属性;
- 直接对象内定义的时候 为true
- 通过属性描述符定义为false
Writable
:表示是否可以修改属性的值;
- 直接对象内定义的时候 为true
- 通过属性描述符定义为false
value
:属性的value值,读取属性时会返回该值,修改属性时,会对其进行修改
- 默认情况下这个值是undefined
使用案例
var obj = {name: "whit",age: 12}Object.defineProperty(obj, "name", {configurable: false,enumerable: false,writable: false,value: "1234"})
存取属性描述符
Configurable&Enumerable
也是存取属性描述符
get
:获取属性时会执行的函数。默认为undefined
set
:设置属性时会执行的函数。默认为undefined
同时定义多个属性
// 多个属性调用Object.defineProperties(obj, {name: {configurable: false,enumerable: false},age: {enumerable: false,writable: false,}})
对象方法补充
获取对象的属性描述符:
- getOwnPropertyDescriptor
- getOwnPropertyDescriptors
禁止对象扩展新属性:preventExtensions
- 给一个对象添加新的属性会失败(在严格模式下会报错);
密封对象,不允许配置和删除属性:seal
- 实际是调用preventExtensions
- 并且将现有属性的configurable:false
冻结对象,不允许修改现有属性: freeze
- 实际上是调用seal
- 并且将现有属性的writable: false
代码案例
// 阻止对象的拓展Object.preventExtensions(obj)obj.address = 12//密封对象 不能进行配置Object.seal(obj)delete obj.name// 冻结对象Object.freeze(obj)obj.name = "ske"
前端进阶JS函数增强与对象增强相关推荐
- 前端进阶-ES6函数
箭头函数 将函数转换为箭头函数 const upperizedNames = ['Farrin', 'Kagure', 'Asser'].map(function(name) { return nam ...
- api日常总结:前端常用js函数和CSS常用技巧
我的移动端media html{font-size:10px} @media screen and (min-width:321px) and (max-width:375px){html{font- ...
- [04]Web前端进阶—JS伪数组
js伪数组 一.伪数组的特点 二.伪数组 常见的伪数组 伪数组转真 三.最后 一.伪数组的特点 具有lenght属性 可以使用下标访问数据 不具有数组的方法,比如push( ),pop( )等 二.伪 ...
- 前端05.js入门之BOM对象与DOM对象。
一.关于BOM对象. BOM(浏览器对象模型),可以对浏览器窗口进行访问和操作.使用 BOM,开发者可以移动窗口.改变状态栏中的文本以及执行其他与页面内容不直接相关的动作. 用于操控用户浏览器. 1. ...
- JS 函数参数arguments对象(实例)
实例(统计所有数值的和) <!DOCTYPE html> <html> <head> <meta charset="utf-8"> ...
- IT:前端进阶技术路线图(初级→中级→高级)之初级(研发工具/HTML/CSS/JS/浏览器)/中级(研发链路/工程化/库/框架/性能优化/工作原理)/高级(搭建/中后台/体验管理等)之详细攻略
IT:前端进阶技术路线图(初级→中级→高级)之初级(研发工具/HTML/CSS/JS/浏览器)/中级(研发链路/工程化/库/框架/性能优化/工作原理)/高级(搭建/Node/IDE/中后台/体验管理/ ...
- java socket中属性详解_前端开发:关于Vue组件中的data属性值是函数而不是对象的详解...
最近在搞关于前端开发的基础知识归纳,发现了不少经典知识点,那么本篇博文就来分享一个经典的知识点:Vue组件中的data属性值为什么是函数而不是对象.首先来了解一下Vue组件的使用理念:在Vue组件使用 ...
- const的使用 || 对象增强写法 (对象字面量)
const的使用 <!DOCTYPE html> <html lang="en"> <head><meta charset="U ...
- 【java学习之路】(javaWeb篇)005.Js之DOM、对象、函数上下文
节点树 节点[element]即为标签 概述:静态页面骨架是由标签组成,标签之间关系很像一颗大树,简称为节点树. 如下图:静态页面标签之间关系图,很像一颗大树,因为前端人称之为节点树. 认识DOM 概 ...
最新文章
- 如何避免GUIDE自动代码的Warning
- 你的第一个AngularJS应用--教程二:基架、建立和測试的工具
- Java 8 中的工厂方法模式
- 响应式织梦通用企业网站后台模板(自适应手机端)
- Java 字符编码与解码
- 电商咄咄逼人的黑色星期五促销横BANNER设计模板
- php集合与数组的区别,php数组和链表的区别总结
- 了解SQL Server中的GUID数据类型
- 基于JMS规范的ActiveMQ
- WINDOWS使用命令行关闭休眠功能
- 基于安卓/android/微信小程序的个人健康打卡系统APP-#计算机毕业设计
- 超级详细的pytest测试和allure测试报告
- Android系统自带的层次状态机StateMachine(Hierarchical State Machine)
- java 源文件结构_A005Java源文件结构
- 友盟php接入统计,ionic2 接入友盟统计
- 计算机操作系统-文件管理
- Python中的setattr()和getattr()
- 前端学习记录(十一) 一个“屡教不改”的错误
- Delphi 对对碰外挂 记录
- Android仿miui11风格,华为EMUI10对比小米MIUI11,到底谁才是最好用的系统?