面试基础知识-2021.11更新

基础

跨域问题

当协议、子域名、主域名、端口号中任意一个不相同时,都算作不同域。不同域之间相互请求资源,就算作“跨域”。
第一:如果是协议和端口造成的跨域问题“前台”是无能为力的。

第二:在跨域问题上,仅仅是通过“URL 的首部”来识别而不会根据域名对应的 IP 地址是否相同来判断。“URL 的首部”可以理解为“协议, 域名和端口必须匹配”。
跨域并不是请求发不出去,请求能发出去,服务端能收到请求并正常返回结果,只是结果被浏览器拦截了。

解决办法

  1. JSONP 方式
    利用 <script> 标签没有跨域限制的漏洞,网页可以得到从其他来源动态产生的 JSON 数据。JSONP 请求一定需要对方的服务器做支持才可以。 JSONP 优点是简单兼容性好,可用于解决主流浏览器的跨域数据访问的问题。缺点是仅支持 get 方法具有局限性,不安全可能会遭受 XSS 攻击。
  2. cors 方式
    CORS 需要浏览器和后端同时支持。IE 8 和 9 需要通过 XDomainRequest 来实现。浏览器会自动进行 CORS 通信,实现 CORS 通信的关键是后端。只要后端实现了 CORS,就实现了跨域。服务端设置 Access-Control-Allow-Origin 就可以开启 CORS。 该属性表示哪些域名可以访问资源,如果设置通配符则表示所有网站都可以访问资源。虽然设置 CORS 和前端没什么关系,但是通过这种方式解决跨域问题的话,会在发送请求时出现两种情况,分别为简单请求和复杂请求。
  3. postmessage
    postMessage()方法允许来自不同源的脚本采用异步方式进行有限的通信,可以实现跨文本档、多窗口、跨域消息传递。
  4. websocket
  5. Node 中间件两次代理
  6. Nginx 反向代理

思否资料
掘金资料

JS 基础

  1. js 基本数据类型 值类型:字符串(String)、数字(Number)、布尔(Boolean)、对空(Null)、未定义(Undefined)、Symbol。 引用数据类型:对象(Object)、数组(Array)、函数(Function)。

  2. == 和 === 的问题
    == 在做比较的时候进行了隐式类型转换
    参考资料

  3. new 一个对象时发生了什么
    new Fun()会进行几个步骤:
    1、创建一个空对象,并且 this 引用该对象,同时还继承了该函数的原型。
    2、this.name 这种属性和方法被加入到 this 引用的对象中。
    3、该函数有 return,如果有,但是返回值是基本类型(Number,String,Boolean,undefined,null)时,会忽略掉此 return 并返回 this(this 引用的对象),如果返回值是引用类型(对象),则返回该对象,this 会被忽略
    4、该函数没有 return,则默认返回 this 引用的对象
    这里我们把 A 函数的返回值设置为一个 Object 类型,则这个时候执行 new A 返回的就是 A 函数的返回值{}.如果我们把 A 的返回值设置为 return [];那么我们在 new A 的时候也相应的得到一个空数组.
    new 操作符具体干了什么呢?

    1. 创建一个空对象,并且 this 变量引用该对象,同时还继承了该函数的原型。
    2. 属性和方法被加入到 this 引用的对象中。
    3. 新创建的对象由 this 所引用,并且最后隐式的返回 this 。
      参考资料
  4. js 原型和原型链
    在 javascript 中,函数可以有属性。 每个函数都有一个特殊的属性叫作原型(prototype)

  5. Promise 相关题目
    Promise 首先解决回调嵌套地狱问题,
    ES6 系列之 Promise
    题目资料

  6. 50 道 JS 基础面试题
    链接

  7. 谈谈你对 ECMAScript6 的理解
    资料

  8. 回流和重绘
    当渲染树中的一部分(或全部)因为元素的规模尺寸,布局,隐藏等改变而需要重新构建。这就称为回流(reflow)。每个页面至少需要一次回流,就是在页面第一次加载的时候。在回流的时候,浏览器会使渲染树中受到影响的部分失效,并重新构造这部分渲染树。完成回流后,浏览器会重新绘制受影响的部分到屏幕中,该过程成为重绘
    回流和重绘介绍(掘金)

  9. js 数组有哪些原生方法,列举一下
    pop、push、shift、unshift、splice、reverse、sort、concat、join、slice、toString、indexOf、lastIndexOf、reduce、reduceRight
    forEach、map、filter、every、some

  10. 什么是 Cookie 隔离?(或者:请求资源的时候不要带 cookie 怎么做)
    通过使用多个非主要域名来请求静态文件,如果静态文件都放在主域名下,那静态文件请求的时候带有的 cookie 的数据提交给 server 是非常浪费的,还不如隔离开。因为 cookie 有域的限制,因此不能跨域提交请求,故使用非主要域名的时候,请求头中就不会带有 cookie 数据,这样可以降低请求头的大小,降低请求时间,从而达到降低整体请求延时的目的。同时这种方式不会将 cookie 传入 server,也减少了 server 对 cookie 的处理分析环节,提高了 server 的 http 请求的解析速度。

  11. 渐进增强与优雅降级
    渐进增强:针对低版本浏览器进行构建页面,保证最基本的功能,然后再针对高级浏览器进行效果、交互等改进,达到更好的用户体验。
    优雅降级:一开始就构建完整的功能,然后再针对低版本浏览器进行兼容。

  12. Web Worker 和 Web Socket
    web socket:在一个单独的持久连接上提供全双工、双向的通信。使用自定义的协议(ws://、wss://),同源策略对 web socket 不适用。
    web worker:运行在后台的 JavaScript,不影响页面的性能。
    创建 worker:var worker = new Worker(url);
    向 worker 发送数据:worker.postMessage(data);
    接收 worker 返回的数据:worker.onmessage
    终止一个 worker 的执行:worker.terminate();
    资料(掘金)

  13. JS 里面什么是闭包
    闭包是在一个函数里声明了另外一个函数,并且这个函数访问了父函数作用域里的变量。

  14. 箭头函数与 this
    call 和 apply 都是调用函数的方法 call 需要列举每个参数,apply 可以传入参数数组
    call 在调用的时候可以指定 this
    window.setTimeout()和 window.setInterval()中 this 的指向是 window 对象

    箭头函数的写法

    1. 规则一:箭头函数只能用赋值式写法,不能用声明式写法
    2. 规则二:如果参数只有一个,可以不加括号,如果没有参数或者参数多于一个就需要加括号
    3. 规则三:如果函数体只有一句话,可以不加花括号
    4. 规则四:如果函数体没有括号,可以不写 return,箭头函数会帮你 return

    箭头函数的特性

    1. 箭头函数的特性一:默认绑定外层 this
    2. 箭头函数的特性二:不能用 call 方法修改里面的 this

    参考资料

  15. JavaScript 中 apply、call、bind 的区别与用法
    apply() 方法调用一个函数, 其具有一个指定的 this 值,以及作为一个数组(或类似数组的对象)提供的参数。 语法 func.apply(thisArg, [argsArray])
    call() 方法调用一个函数, 其具有一个指定的 this 值和分别地提供的参数(参数的列表)。 语法 fun.call(thisArg, arg1, arg2, …)
    bind()方法创建一个新的函数, 当被调用时,将其 this 关键字设置为提供的值,在调用新函数时,在任何提供之前提供一个给定的参数序列。 语法 fun.bind(thisArg, 队列 or 数组)()

css 基础

  1. css 哪些属性可以继承
    字体系列属性、文本系列属性、元素可见性:visibility、表格布局属性:caption-side、列表属性:list-style-type、设置嵌套引用的引号类型:quotes、光标属性:cursor
    参考资料

  2. 50 道 css 题
    资料

  3. 清除浮动

    1
    2
    3
    <div class="father clearfix">
    <div class="b">我是儿子</div>
    </div>
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    .father {
    background: black;
    }

    .b {
    width: 120px;
    height: 120px;
    float: left;
    background: darkred;
    }
    .clearfix:after {
    content: '.';
    clear: both;
    display: block;
    height: 0;
    overflow: hidden;
    visibility: hidden;
    }
    .clearfix {
    /* 触发 hasLayout */
    zoom: 1;
    }

    清除浮动有好几种方法,不过现在最流行的就是 after 伪元素清除浮动(不适用于 IE)。第二种是空标签清除浮动,子元素最后添加一个空标签,然后加上clear:both(w3c 推荐,浮动闭合标签,但是会额外增加无用元素),第三种是在父元素上面添加overflow:auto;属性(具有不确定性的影响,建议多个浏览器调试)。
    简书资料
    CSDN 资料

  4. BFC 原理及用法
    BFC(Block Formatting Context)直译为“块级格式化上下文”。
    是 W3C CSS 2.1 规范中的一个概念,它决定了元素如何对其内容进行定位,以及与其他元素的关系和相互作用 当涉及到可视化布局的时候,Block Formatting Context 提供了一个环境,HTML 元素在这个环境中按照一定规则进行布局。一个环境中的元素不会影响到其它环境中的布局
    怎样才能形成 BFC

    1. float 的值不能为 none
    2. overflow 的值不能为 visible
    3. display 的值为 table-cell, table-caption, inline-block 中的任何一个
    4. position 的值不为 relative 和 static

      BFC 全称为块级格式化上下文 (Block Formatting Context) 。BFC 是 W3C CSS 2.1 规范中的一个概念,它决定了元素如何对其内容进行定位以及与其他元素的关系和相互作用,当涉及到可视化布局的时候,Block Formatting Context 提供了一个环境,HTML 元素在这个环境中按照一定规则进行布局。一个环境中的元素不会影响到其它环境中的布局。比如浮动元素会形成 BFC,浮动元素内部子元素的主要受该浮动元素影响,两个浮动元素之间是互不影响的。这里有点类似一个 BFC 就是一个独立的行政单位的意思。可以说 BFC 就是一个作用范围,把它理解成是一个独立的容器,并且这个容器里 box 的布局与这个容器外的 box 毫不相干。

    触发 BFC 的条件:

    • 根元素或其它包含它的元素
    • 浮动元素 (元素的 float 不是 none)
    • 绝对定位元素 (元素具有 position 为 absolute 或 fixed)
    • 内联块 (元素具有 display: inline-block)
    • 表格单元格 (元素具有 display: table-cell,HTML 表格单元格默认属性)
    • 表格标题 (元素具有 display: table-caption, HTML 表格标题默认属性)
       具有 overflow 且值不是 visible 的块元素
    
    • 弹性盒(flex 或 inline-flex)
       display: flow-root
       column-span: all
    
  5. css 选择器及优先级
    !important,内联样式(1000),ID 选择器(0100),类选择器(class)/属性选择器([属性])/伪类选择器(0010)(a:hover,a:link, a:active, focus,a:visited, before, after, ::selection),
    元素选择器/伪元素选择器(0001)(:first-letter ,:fist-line, :before),
    关系选择器/通配符选择器(0000)

浏览器及浏览器兼容性问题

  1. 浏览器兼容性问题 掘金总结

    1. 安装 Normalize.css 来磨平各浏览器之间的样式差异问题

    2. 使用 html5shiv.js 解决 IE9 以下对于新增 H5 标签不支持的问题

      1
      2
      3
      <!--[if lt IE 9]>
      <script type="text/javascript" src="https://cdn.bootcss.com/html5shiv/3.7.3/html5shiv.min.js"></script>
      <![endif]-->
    3. 使用 respond.js 解决 ie9 以下浏览器不支持 CSS3 Media Query 的问题。

      1
      <script src='https://cdn.bootcss.com/respond.js/1.4.2/respond.min.js' />
    4. 浏览器 CSS 兼容前缀

      1
      2
      3
      4
      5
      6
      7
      8
      9
      -o-transform: rotate(7deg); // Opera

      -ms-transform: rotate(7deg); // IE

      -moz-transform: rotate(7deg); // Firefox

      -webkit-transform: rotate(7deg); // Chrome

      transform:rotate(7deg); // 统一标识语句
  2. BFC 解决边距重叠问题
    当相邻元素都设置了 margin 边距时,margin 将取最大值,舍弃小值。为了不让边距重叠,可以给子元素加一个父元素,并设置该父元素为 BFC:overflow: hidden;

1
2
3
4
5
6
7
8
9
<div class="box" id="box">
<p>Lorem ipsum dolor sit.</p>

<div style="overflow: hidden;">
<p>Lorem ipsum dolor sit.</p>
</div>

<p>Lorem ipsum dolor sit.</p>
</div>

掘金总结

  1. 输入一个 URL 回车后发生了什么(经典面试题)

Vue 基础

  1. vue 的生命周期(8 个)
    beforeCreate、created、beforeMount、mounted、beforeUpdate、updated、beforeDestroy、destroyed
    参考资料

  2. Vue 常问的面试题
    参考资料
    参考资料 CSDN

  3. 自定义组件 v-model 的用法
    emm 之前用过 .sync 不过在自定义组件上用v-model还真没用过。
    这个用法在 vue 2.2 版本添加 具体使用方法如下
    子组件:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    <template>
    <div>
    {{ msg }}
    </div>
    </template>

    <script>
    export default {
    model: {
    prop: 'msg',//这个字段,是指父组件设置 v-model 时,将变量值传给子组件的 msg
    event: 'ok'//这个字段,是指父组件监听 parent-event 事件
    },
    props: {
    msg: String//此处必须定义和model的prop相同的props,因为v-model会传值给子组件
    },
    watch: {
    msg(newVal, oldVal) {
    if (newVal.length > 3) {
    this.$emit('ok', '输入字符已经超过3个') //通过 emit 触发ok,将字符串传递给父组件的v-model绑定的变量
    }
    }
    }
    }
    </script>

    <style lang="scss" scoped>
    </style>

    父组件:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    <template>
    <div class="home">
    <Vmd v-model="testMsg"></Vmd>
    <input
    type="text"
    v-model="testMsg"
    >
    </div>
    </template>

    <script>
    import Vmd from "@/components/Vmodel.vue";
    export default {
    name: "home",
    components: {
    Vmd
    },
    data() {
    return {
    testMsg: 'a'
    }
    }
    };
    </script>

    还有.sync用法,也挺简单,具体见资料
    掘金资料

  4. vue-router 的几个钩子函数的使用
    通过直接更改 Url 触发哪个函数钩子。

  5. v-for 和 v-if 的优先级及为什么不能在一起使用
    因为 v-for 优先级比 v-if 高,所以如果一起用的话 每次动一下数据 都会渲染整个列表,设置的 v-if 都走一下 相当于多操作了 DOM,建议你先把数据处理好(内存中 开销比 DOM 小)然后再渲染
    Vue 风格指南

  6. vue 路由 history 模式刷新页面出现 404 问题
    vue hash 模式下,URL 中存在’#’,用’history’模式就能解决这个问题。但是 history 模式会出现刷新页面后,页面出现 404。解决的办法是用 nginx 配置一下

    1
    2
    3
    4
    5
    6
    7
    8
    location /{
    root /data/nginx/html;
    index index.html index.htm;
    if (!-e $request_filename) {
    rewrite ^/(.*) /index.html last;
    break;
    }
    }

    第二种方法更改 vue 打包配置文件
    掘金
    思否
    文档

  7. vuex 相当于数据库和状态管理中心
    注意问题:模块内的 getter, mutation,action 是注册在全局空间的,state 只注册在局部命名空间的;
    解决 vuex 数据刷新消失问题
    stack overflow cookie 存储方式
    记得还有一个

  8. v-if 触发 destoryed 钩子 v-show 不会触发
    组件销毁不会清除定时器,setTimeout 放到了异步任务队列,哪怕组件清楚了也会执行回调。

  9. vue 兄弟组件通信的三种方式
    一、子传父 父传子
    二、Vuex
    三、创建一个事件总线 新建一个 vue 实例当做事件总线 然后使用这个实例的$on和$emit 来进行传递信息

  10. 组件里面 data 必须是一个函数
    Object 是引用数据类型, 每个组件的 data 都是内存的同一个地址,一个数据改变了其他也改变了。当一个组件被定义,data 必须声明为返回一个初始数据对象的函数,因为组件可能被用来创建多个实例。如果 data 仍然是一个纯粹的对象,则所有的实例将共享引用同一个数据对象!通过提供 data 函数,每次创建一个新实例后,我们能够调用 data 函数,从而返回初始数据的一个全新副本数据对象。

  11. vue 中$set 的使用场景
    一、通过数组的下标去修改数组的值,数据已经被修改了,但是不触发 updated 函数,视图不更新,
    二、vue 中检测不到对象属性的添加和删除
    vue 在创建实例的时候把 data 深度遍历所有属性,并使用 Object.defineProperty 把这些属性全部转为 getter/setter。让 Vue 追踪依赖,在属性被访问和修改时通知变化。所以属性必须在 data 对象上存在才能让 Vue 转换它,这样才能让它是响应的。
    当你在对象上新加了一个属性 newProperty,当前新加的这个属性并没有加入 vue 检测数据更新的机制(因为是在初始化之后添加的),vue.$set 是能让 vue 知道你添加了属性, 它会给你做处理

  12. 计算属性 vs 方法
    计算属性是基于它们的响应式依赖进行缓存的。只在相关响应式依赖发生改变时它们才会重新求值。这就意味着只要 message 还没有发生改变,多次访问 reversedMessage 计算属性会立即返回之前的计算结果,而不必再次执行函数。如果不希望有缓存 那么使用方法来代替。

React 及 RN 基础

  1. RN 生命周期
    getDefaultProps、getInitialState、componentWillMount、render、componentDidMount、shouldComponentUpdate、componentWillUpdate、componentDidUpdate、componentWillReceiveProps、componentWillUnmount
    参考资料
  2. React 有关的面试题
    掘金资料
  3. setState 之后发生了什么

Http 协议

资料

  1. Http 的请求报文和响应报文分为几个部分
    一个 HTTP 请求报文由请求行(request line)、请求头部(header)、空行和请求数据 4 个部分组成
    HTTP 响应也由三个部分组成,分别是:状态行、消息报头、响应正文。
  2. 常见的 HTTP 状态码
    1xx(临时响应)表示临时响应并需要请求者继续执行操作的状态代码。代码 说明
    2xx (成功)表示成功处理了请求的状态代码。代码 说明
    3xx (重定向) 表示要完成请求,需要进一步操作。 通常,这些状态代码用来重定向。代码 说明
    4xx(客户端请求错误) 这些状态代码表示请求可能出错,妨碍了服务器的处理。代码 说明
    5xx(服务器错误)这些状态代码表示服务器在尝试处理请求时发生内部错误。 这些错误可能是服务器本身的错误,而不是请求出错。代码 说明
    博客园简洁
    常见的 14 种状态码
  3. Get 和 Post 的区别
    GET 在浏览器回退时是无害的,而 POST 会再次提交请求。
    GET 产生的 URL 地址可以被 Bookmark,而 POST 不可以。
    GET 请求会被浏览器主动 cache,而 POST 不会,除非手动设置。
    GET 请求只能进行 url 编码,而 POST 支持多种编码方式。
    GET 请求参数会被完整保留在浏览器历史记录里,而 POST 中的参数不会被保留。
    GET 请求在 URL 中传送的参数是有长度限制的,而 POST 么有。
    对参数的数据类型,GET 只接受 ASCII 字符,而 POST 没有限制。
    GET 比 POST 更不安全,因为参数直接暴露在 URL 上,所以不能用来传递敏感信息。
    GET 参数通过 URL 传递,POST 放在 Request body 中。
  4. RESTful Api 四种操作对应说明
    POST Create 新增一个没有 id 的资源
    GET Read 取得一个资源
    PUT Update 更新一个资源。或新增一个含 id 资源(如果 id 不存在)
    DELETE Delete 删除一个资源

Webpack 面试题基础

资料

面试题

常见面试题

博客园资料
博客园资料 2
50 道 JS 面试题 CSDN
几道笔试算法题
this apply call

框架带来的问题(Vue+React)

  1. 为什么 v-for 渲染的时候需要带 key 值,并且不推荐使用 index
    首先 Vue 在 2.0 也加入了 diff 算法,列表循环带 key 值是为了更高效的渲染列表。其原理是 diff 算法会比较虚拟 Dom 的差异,然后能复用的地方会根据 key 值复用,然后将差异的部分渲染到 DOM 树里面。如果是在列表后面 push 一个数据,那么 index 值是顺序加一的,并且不影响原来列表的顺序,在此数据之前的列表数据都会得到复用,而 Dom 只渲染此条数据。但是假如有一条数据在列表中间插入,那么以 index 为 key 的值则和原来的列表数据不对应,会导致此条数据及之后的数据全部重新渲染而不会得到复用。因此建议尽量不要使用 index 值作为列表的 key 值。
    简单实现一个 Virtual DOM
    为什么使用 v-for 时必须添加唯一的 key?

JS 面试题

  1. 给定一个字符串 var str=’abcabcefbbd’。1)求字符 a 出现的次数。2)求出现次数最多的字符是,出现的次数是多少

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    function getStr() {
    let str = 'abcabcefbbd'
    let beatStr = {}
    let moreStr = ''
    let num = 0
    for (let item of str) {
    if (beatStr[item]) {
    beatStr[item]++
    } else {
    beatStr[item] = 1
    }
    if (beatStr[item] > num) {
    num = beatStr[item]
    moreStr = item
    }
    }
    console.log(num, moreStr, beatStr)
    return beatStr
    }
    getStr()

    输出4 'b' {a: 2, b: 4, c: 2, e: 1, f: 1}

  2. 以下代码输出多少

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    var c = 0
    function print() {
    console.log(window.c)
    console.log(c)
    }
    function plus() {
    setTimeout(function () {
    c += 1
    }, 1000)
    }
    plus()
    print()

    输出:window.c = 0 c = 0

  3. js 实现一个千分位分割方法
    js 实现一个千位符分割方法: parseInt('11123123231').toLocaleString() "111,231,232,313,213"
    或者是

    1
    2
    3
    var str = '100000000000',
    reg = /(?=(\B\d{3})+$)/g
    console.log(str.replace(reg, ','))

    参考资料

  4. 实现一个拍平数组,实现以下需求
    var source = ['1',['2',['3',['4']]],'5',['6']]
    ['1','2','3','4','5','6']
    解题思路:递归
    var ary = [1,23,4];console.log(ary instanceof Array)//true; instanceof 判断是否是数组

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    var source = ['1', ['2', ['3', ['4']]], '5', ['6']]
    var sortArr = []

    function sort(arr) {
    for (let i in arr) {
    if (arr[i] instanceof Array) {
    sort(arr[i])
    } else {
    sortArr.push(arr[i])
    }
    }
    }
    sort(source)
    // eslint-disable-next-line no-console
    console.log(sortArr)
    // [ '1', '2', '3', '4', '5', '6' ]
  5. 函数柯里化 任意参数数相加

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    var adder = function () {
    var _args = []
    return function () {
    if (arguments.length === 0) {
    return _args.reduce(function (a, b) {
    return a + b
    })
    }
    ;[].push.apply(_args, [].slice.call(arguments))
    // _args.push(...arguments)
    return arguments.callee
    }
    }
    var sum = adder()
    console.log(sum) // Function

    sum(100, 200)(300) // 调用形式灵活,一次调用可输入一个或者多个参数,并且支持链式调用
    sum(400)
    console.log(sum()) // 1000 (加总计算)

    参考资料:dalao
    参考资料:掘金
    参考资料:arguments.callee

  6. 数组[1,2,3,4,5]如何变成[1,2,3,’a’,’b’,5]
    使用 ES6 的扩展运算符

    1
    2
    3
    let a = [1,2,3,4,5]
    let b = ['a'.'b']
    a.splice(3,1,...b)
  7. 以下代码输出多少

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    const length = 10
    function fn() {
    console.log(this.length)
    }

    const obj = {
    length: 5,
    method: function (fn) {
    fn()
    arguments[0]()
    },
    }

    obj.method(fn, 1)

    输出:10,2

    method 这个函数传入了两个参数,一个参数为 fn(),fn()为普通函数,this 指向函数的调用者,此时指向全局(也可以看这个函数前面没有点),所以运行结果为 10,arguments 是函数的所有参数,是一个类数组的对象,arguments0,可以看成是 arguments.0(),调用这个函数的是 arguments,此时 this 就是指 arguments,this.length 就是 angument.length,就是传入的参数的总个数 2

Author: XavierShi
Link: https://blog.xaviershi.com/2019/04/23/面试基础知识/
Copyright Notice: All articles in this blog are licensed under CC BY-NC-SA 4.0 unless stating additionally.