前端面试 75 道题,看完的人少之又少 (中)( 二 )


import React from 'react';class MyComponent extends React.Component {constructor(props){super(props);this.state = {value : ""}this.handleChange = this.handleChange.bind(this);// 将 “handleChange” 方法绑定到 “MyComponent” 组件}handleChange(e){//do something amazing here}render(){return (<>)}}31. 什么是函数式编程? JavaScript 的哪些特性使其成为函数式语言的候选语言?函数式编程(通常缩写为FP)是通过编写纯函数 , 避免共享状态、可变数据、副作用 来构建软件的过程 。 数式编程是声明式 的而不是命令式 的 , 应用程序的状态是通过纯函数流动的 。 与面向对象编程形成对比 , 面向对象中应用程序的状态通常与对象中的方法共享和共处 。
函数式编程是一种编程范式, 这意味着它是一种基于一些基本的定义原则(如上所列)思考软件构建的方式 。 当然 , 编程范示的其他示例也包括面向对象编程和过程编程 。
函数式的代码往往比命令式或面向对象的代码更简洁 , 更可预测 , 更容易测试 - 但如果不熟悉它以及与之相关的常见模式 , 函数式的代码也可能看起来更密集杂乱 , 并且 相关文献对新人来说是不好理解的 。
JavaScript支持闭包和高阶函数是函数式编程语言的特点 。
32. 什么是高阶函数?高阶函数只是将函数作为参数或返回值的函数 。
function higherOrderFunction(param,callback){return callback(param);}33. 为什么函数被称为一等公民?在JavaScript中 , 函数不仅拥有一切传统函数的使用方式(声明和调用) , 而且可以做到像简单值一样赋值(var func = function(){})、传参(function func(x,callback){callback();})、返回(function(){return function(){}}) , 这样的函数也称之为第一级函数(First-class Function) 。 不仅如此 , JavaScript中的函数还充当了类的构造函数的作用 , 同时又是一个Function类的实例(instance) 。 这样的多重身份让JavaScript的函数变得非常重要 。
34. 手动实现 Array.prototype.map 方法map() 方法创建一个新数组 , 其结果是该数组中的每个元素都调用一个提供的函数后返回的结果 。
function map(arr, mapCallback) {// 首先 , 检查传递的参数是否正确 。if (!Array.isArray(arr) || !arr.length || typeof mapCallback !== 'function') {return [];} else {let result = [];// 每次调用此函数时 , 我们都会创建一个 result 数组// 因为我们不想改变原始数组 。for (let i = 0, len = arr.length; i < len; i++) {result.push(mapCallback(arr[i], i, arr));// 将 mapCallback 返回的结果 push 到 result 数组中}return result;}}35. 手动实现Array.prototype.filter方法filter() 方法创建一个新数组, 其包含通过所提供函数实现的测试的所有元素 。
function filter(arr, filterCallback) {// 首先 , 检查传递的参数是否正确 。if (!Array.isArray(arr) || !arr.length || typeof filterCallback !== 'function'){return [];} else {let result = [];// 每次调用此函数时 , 我们都会创建一个 result 数组// 因为我们不想改变原始数组 。for (let i = 0, len = arr.length; i < len; i++) {// 检查 filterCallback 的返回值是否是真值if (filterCallback(arr[i], i, arr)) {// 如果条件为真 , 则将数组元素 push 到 result 中result.push(arr[i]);}}return result; // return the result array}}36. 手动实现Array.prototype.reduce方法reduce() 方法对数组中的每个元素执行一个由您提供的reducer函数(升序执行) , 将其结果汇总为单个返回值 。
function reduce(arr, reduceCallback, initialValue) {// 首先 , 检查传递的参数是否正确 。if (!Array.isArray(arr) || !arr.length || typeof reduceCallback !== 'function'){return [];} else {// 如果没有将initialValue传递给该函数 , 我们将使用第一个数组项作为initialValuelet hasInitialValue = http://kandian.youth.cn/index/initialValue !== undefined;let value = hasInitialValue ? initialValue : arr[0];、// 如果有传递 initialValue , 则索引从 1 开始 , 否则从 0 开始for (let i = hasInitialValue ? 0 : 1, len = arr.length; i < len; i++) {value = reduceCallback(value, arr[i], i, arr);}return value;}}37. arguments 的对象是什么?arguments对象是函数中传递的参数值的集合 。 它是一个类似数组的对象 , 因为它有一个length属性 , 我们可以使用数组索引表示法arguments[1]来访问单个值 , 但它没有数组中的内置方法 , 如:forEach、reduce、filter和map 。
我们可以使用Array.prototype.slice将arguments对象转换成一个数组 。
function one() {return Array.prototype.slice.call(arguments);}注意:箭头函数中没有arguments对象 。