这篇文章主要讲解了“JavaScript基础函数和方法详解”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“JavaScript基础函数和方法详解”吧!
一、函数和方法的区别
二、如何写好一个函数
2.1 命名准确
2.1.1 函数命名
2.1.2 参数命名
2.2 函数注释
2.2.1 参数注释
2.3 函数参数
2.3.1 参数默认值
2.3.2 对象参数
2.3.3 参数数量
2.3.4 参数类型防御
2.4 函数的返回
2.4.1 幂等函数
2.4.2 纯函数
2.4.3 return null
函数和方法的区别
函数(function):函数是带有名称和参数的 JavaScript 代码段,可以一次定义多次调用。
方法(method):当将函数和对象写在一起时,函数就变成了“方法”,比如当函数赋值给对象的属性时,我们便称其为“方法”。
在 JS 中,除了变量,用的最多的应该就是函数了,函数是 Javascript 的第一公民。
函数的命名需要明确,语义清晰,简单概括函数的功能。我们不要想着代码简短而缩短函数名称,这并不会提高什么性能或效率,相反,一个函数名称若不够清晰,往往其他人无法理解。
尽量使用动词,比如:getXxxxx、setXxxxx,动词在前面,语义就能更加清晰。
强调语义化,参数命名让调用者更清晰的知道该传入什么,对应什么参数。当然,像一些通用命名还是可接受的,像 callback,fn,即使不看注释,往往我也知道这里的参数要做什么,传什么。
/** * 时间格式化工具函数 * * @param { (Date | number) } date - 时间 * @param { string } unit - 转换格式 */ export const timeFormat = (date: Date | number | string, unit: string) => { if (!date) { return '' } if (typeof date === 'string') return date; if (typeof date === 'number') { date = new Date(date); } const year = date.getFullYear(); const month = date.getMonth() + 1; const day = date.getDate(); const hour = date.getHours(); const minute = date.getMinutes(); const second = date.getSeconds(); if (unit === 'year') return `${year}`; if (unit === 'month') return `${year}-${month}`; if (unit === 'day') return `${year}-${month}-${day}`; if (unit === 'hour') return `${year}-${month}-${day} ${hour}`; if (unit === 'minute') return `${year}-${month}-${day} ${hour}:${minute}`; if (unit === 'second') return `${year}-${month}-${day} ${hour}:${minute}:${second}`; }
/** * 时间格式化工具函数 * * @param { (Date | number) } date - 时间 * @param { string } unit - 转换格式 */
@param { type } 参数 - 参数解释:type 表明的是参数的类型,比如 string,number,当有多个参数类型的时候,可以这么来标识 { (string|string[]) },表示这个参数可以是字符串或者字符串数组。
对象属性:需要解释对象的每一个属性
/** * 将项目分配给员工的函数 * * @param {Object} employee - 项目员工 * @param {string} employee.name - 项目员工的姓名 * @param {string} employee.department - 项目员工的部门 */ Project.prototype.assign = function(employee) { // ... };
可选参数:
/** * 时间格式化工具函数 * * @param { (Date | number | string) } date - 时间 * @param { string } [unit] - 转换格式 */ export const timeFormat = (date: Date | number | string, unit: string) => { // ... }
默认值:
/** * 时间格式化工具函数 * * @param { (Date | number) } date - 时间 * @param { string } [unit = 'second'] - 转换格式 */ export const timeFormat = (date: Date | number | string, unit = 'second') => { // ... }
export const timeFormat = (date: Date, unit = 'second') => { // ... }
async function printer_proxy_print( html_str: string, file_path: string, device: string | undefined, orientation: number, printer_mode: string, width: number, height: number, scale: number, from: number, to: number, left_offset: number, top_offset: number, pdf_tools: string | undefined, begin_page = 1, end_page = 1, repeat_times = 1, print_type: string ) { // ... }
可以给参数默认值,这样可以只传前面几个必要的参数,像这样调用。
async function printer_proxy_print( html_str: string, file_path: string, device = 'pc', orientation = 'xxx', printer_mode = 'xxx', width = 123, height = 123, scale = 123, from = 123, to = 123, left_offset = 123, top_offset = 123, pdf_tools = 123, begin_page = 1, end_page = 1, repeat_times = 1, print_type = 'base64' ) { // ... } await printer_proxy_print(html_str, file_path);
上面的方法看似可行,实际上,当我中间某个参数不一样的时候,我就需要把这个参数前面的参数都传一遍。这样显然不可行。所以当参数多的时候,我们需要用对象解构的方式传参。
async function printer_proxy_print({ html_str, file_path, device = 'pc', orientation = 'xxx', printer_mode = 'xxx', width = 123, height = 123, scale = 123, from = 123, to = 123, left_offset = 123, top_offset = 123, pdf_tools = 123, begin_page = 1, end_page = 1, repeat_times = 1, print_type = 'base64' }) { // ... } await printer_proxy_print({html_str, file_path});
解构的好处便是我可以随便传我想要的某几个参数,而不用在意顺序问题。不过像这么多参数的函数往往存在问题(具体问题具体分析)。也就是下面提到的参数数量问题。
一个函数的参数越少越好,最多不应该超过3个,参数多往往意味着关系多,逻辑交叉相对也就多了起来。在进行测试的时候,往往也就很难覆盖到所有条件,出问题概率也就加大了。
参数多的时候,有时候也意味着功能多,就违背了 单一功能 的原则。
在 TS 开发前,我们不知道用户会传什么东西进来,这时候往往容易产生类型错误,又或者,我们想实现兼容,像前面的 timeFormat 函数,我们希望用户调用的时候,可以是想对 时间对象 格式化,也可以是对 时间戳 格式化,那我们就需要做一个防御处理。
if (!date) { return '' } if (typeof date === 'string') return date; if (typeof date === 'number') { date = new Date(date); }
不过值得注意的是,即使我们用上了 TS,在大多数情况下,我们确实可以避免参数类型问题,但是这并不绝对,因为我们有时候会直接接受 接口 返回的数据。
我们常说,永远不要相信用户的输入,同样,接口返回的数据我也不信,我们不能保证,后端不会出错,约定好的参数是数组类型,怎么空的时候,你给我个 null 呢?
当然这些情况有时候需要去试错,有时候我们能想到的可能,不要偷懒,给写上类型判断吧。
什么叫幂等,简单来说,输入什么输出什么是固定的,入参决定了出参,不管调用多少次,只要输入一样,结果应该保持一样。
function sum(a: number, b: number) { return a + b; }
幂等函数具有可维护性,相对容易进行单元测试。
纯函数在幂等的条件下,还要求没有副作用。
const dog = { name: 'puppy', age: 2, weight: 30, } if (!dog.color) { console.log('has no color'); } function addColor(dog) { dog.color = 'white'; } addColor(dog); console.log(dog); // {name: "puppy", age: 2, weight: 30, color: "white"}
可以看到,addColor 函数修改了 dog 对象的属性,也就是产生了副作用。
function addColor(dog) { let copyDog = Object.assign({}, dog); copyDog.color = 'white'; return copyDog; }
这样一来,dog 对象的属性就不会修改,addColor 函数是纯函数。
null 在进行处理的时候相对麻烦,需要进行判断,导致了额外的代码,应当返回空对象,或者是空数组,或者抛出异常。
1)函数(function)是一段代码,通过名字来进行调用。它能将一些数据(参数)传递进去进行处理,然后返回一些数据(返回值),也可以没有返回值。
2)方法(method)是通过对象调用的javascript函数。也就是说,方法也是函数,只是比较特殊的函数。他是和一个对象相关联。假设有一个函数是fn,一个对象是obj,那么就可以定义一个method:
obj.method = fn;
obj.method();
3)函数的数据是显式传递
4)方法中的数据是隐式传递的;方法和对象相关。
感谢各位的阅读,以上就是“JavaScript基础函数和方法详解”的内容了,经过本文的学习后,相信大家对JavaScript基础函数和方法详解这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是亿速云,小编将为大家推送更多相关知识点的文章,欢迎关注!
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。