关于javascript:前端面试宝典javascript核心知识篇

44次阅读

共计 14333 个字符,预计需要花费 36 分钟才能阅读完成。

前言:

想零碎学习前端面试题,强烈推荐浏览 在线电子书(反对手机版,不断更新)。

本书特点:零碎全面(涵盖前端核心技术点),简洁,针对性强(针对面试场景设计)。

欢送在 github 上留言反馈

js 原生

如何判断两个对象是不是相等?

  1. 【转成字符串判断】(不反对函数,正则),JSON.stringife(obj);JSON.parse(str)
  2. 插件:

    1. loadsh: 不反对函数和 DOM 节点比拟
  3. 【循环遍历】

什么是 Polyfill?

Polyfill 是一块代码(通常是 web 上的 js),为旧浏览器提供它没有原生反对的较新性能;

抚平不同浏览器之间对 JS 实现的差别

eg:

应用 Silverlight 模仿 html canvas 元素的性能 或 模仿 CSS 实现 rem 单位的反对,或 text-shadow, 其余

<script src="//cdn.polyfill.io/v1/polyfill.min.js" async defer></script>

什么是函数复作用?

做和这个函数性能不相干的事件,现实状态,一个函数只专一实现一件性能

js 实例办法与静态方法的区别,如何注入?

静态方法:

能够间接用类名,办法名去调用的

注入形式:

  • 构造函数:

    • 当做属性写入
    • 自执行函数内,返回一个构造函数,当做属性写入也放入自执行函数
  • class 类:在办法 / 属性前增加 static 字段

实例办法:

不能间接调用,必须先实例化才能够调用

注入形式:

  • 对象,通过原型链 prototype 注入
  • 在 class 类办法的默认状态

class 类的注入

     class Person{
        // 加上 static 就是静态方法,不须要实例化调用
        static getName(name){console.log(` 我的名字是 ${name}`);
        }
        //say 属于实例办法,要先 new 实例化后能力调用
        say(){console.log('开始谈话')
        }
    }

    let china =  new Person();
    china.say();
    Person.getName('JAY')

function 函数的注入

  let Person=function (){}

    /*
    * 静态方法:只针对以后实例,可间接调用
    * */
    Person.say=function (){console.log('我是一个人');
    }


    /*
    * 实例办法:先实例化能力调用,实例办法写在原型链外面
    * */
    Person.prototype.getName=function (name){console.log(` 我的名字是 ${name}`);
    }


    Person.say();  // 失常打印,不能应用   Person.getName('Jay')

    let china=new Person();
    china.getName('JAY');  // 失常打印,不能应用 china.say();

构造函数能过自执行函数注入:

    let Person=(function (){let PersonInner=function (){this.jump=function (){console.log('跳转起来');
            }
        }

        PersonInner.staticMethod=function (){console.log('静态方法');
        }

        return PersonInner;
    })()


    // 静态方法: 间接通过结构函数调用
    Person.staticMethod();


    // 实例办法的调用:要先 new
    let china=new Person();
    china.jump();

堆和栈的区别?

1)相同点:

堆和栈是两种数据结构,都是一种按序排列的数据结构,只能在一端(称为栈顶 top)对数据项进行插入和删除。堆栈是个非凡的存储区,次要性能是临时存放数据和地址。

2)不同点

堆:堆内存个别是由语言运行环境调配治理,如 python 虚拟机管制内存和运行环境

栈:

堆(heap) 栈(stack)
定义 数据存储构造 定义一个变量时,计算机会在内存中开拓一块存储空间来寄存这个变量的值,这块空间叫做栈
时效性 长久化 长期
Context(执行上下文) 全局 部分
内存调配 手动申请 / 开释, 若不开释,程序完结时可能由 OS 回收 主动申请 / 开释(出栈时),零碎调配是有大小限度的,超过就会内存溢出报错
数据寄存类型 对象类型 根本数据类型
特点 / 先进后出

栈示意图(先进后出):

    let obj={name:'girl friend'}
    b=obj;
    b.name='strange';
    console.log(obj);

堆示意图:

    var arr = [1,2,3];
    brr = arr;
    brr[0] = 10;
    alert(arr[0] );

堆栈关系:

【栈】左侧:栈中寄存援用地址,这个地址在计算机中叫做援用变量

【堆】右侧:堆中寄存对象,多个援用地址会指向同一个对象,JS 节俭存储空间

代码的复用有哪几种形式?

函数封装

继承 extend

复制

混入 mixin

借用 apply/call

过程与线程的区别?

过程 线程
尺度划分 大(一个过程至多有一个线程) 小(数量多,并发高)
内存占用 独立内存单元(解决隔离) 共享内存(解决并发,极大提高效率)
基本区别 操作系统资源分配的根本单位 CPU 任务调度和执行的根本单位
性能开销 大(程序切换耗费大,独立执行) 小(同一类线程共享代码与数据空间,领有独立的运行栈和程序计数器(PC)
所处环境 操作系统(可运行过程(程序)) 过程(通过 CPU 调试,每个工夫片中只有一个线程执行)
蕴含关系 过程蕴含线程 线程依赖过程

参考资料:

[每个程序员都会遇到的面试问题:谈谈过程和线程的区别]()

线程和过程的区别是什么?

js 提早加载的形式有哪些?

defer 和 async、动态创建 DOM 形式(创立 script,插入到 DOM 中,加载结束后 callBack)、按需异步载入 js

defer:异步加载,提早执行(文档解析实现后)

async:异步加载,立刻执行

new 操作符具体干了什么呢?

1、创立一个空对象,并且 this 变量援用该对象,同时还继承了该函数的原型。
2、属性和办法被退出到 this 援用的对象中。
3、新创建的对象由 this 所援用,并且最初隐式的返回 this。

var obj = {};
obj.__proto__ = Base.prototype;
Base.call(obj);

参考资料:

javascript 中,new 操作符的工作原理是什么?

解释下变量晋升?

js 引擎的工作形式是,先解析代码,获取所有被申明的变量,而后再一行行地运行。这造成了所有变量的申明语句,都会被晋升到代码头部,这就叫做变量晋升(hoisting).

js 的执行过程?

js 特点:异步,单线程;

一、语法分析
js 脚本代码块加载结束后,进入语法分析,判断 语法是不中正确,如果不正确,向外抛出 语法错误(syntaxError),进行该js代码块的执行,而后持续查找并加载下一个代码块;如果语法正确,则进入预编译阶段

二、预编译阶段

前置常识:
js运行环境:
- 全局环境 :js代码加载结束后,代码进入全局环境)
- 函数环境:函数调用执行时,进入该函数环境,不同函数则函数环境不同
- eval:不倡议应用,有平安、性能问题

预编译阶段过程如下:

函数调用栈

  • 造成执行上下文:进入不同环境创立相应的执行高低,可创立多个
  • 造成函数调用栈:js 引擎以栈的模式解决执行上下文(栈底永远全局执行上下文,栈顶永远是以后执行上下文)

创立执行上下文

  • 创立变量对象
  • 建设作用域链
  • 确定 this 指向

三、执行阶段:

可参考:宏工作与微工作, 事件循环 event loop 介绍

举荐文章:

  • js 引擎的执行过程

js 中的宏工作与微工作,事件循环 event loop?

宏工作(macro-task):

同步工作:js 引擎按主线程按程序执行的工作,一个一个工作执行,造成一个执行栈(函数调用栈)

eg:console.log(11); let a=10;

异步工作 : 不间接进入 js 引擎主线程,而是满足条件时触发,相干的线程将该工作推动 工作队列,期待 js 引擎主线程上的工作执行结束,再读取执行中的工作

eg:ajax, dom 事件,setTimeout

微工作(micro- task)

微工作是在 es6 和 node 环境中呈现的一个工作类型

eg:promise,process.nextTick

js 引擎执行过程:宏工作(同步工作)—> 微工作 –> 宏工作(异步工作)

柯里化函数的例子,并阐明柯里化的益处?

柯里化是一种模式,其中一个具备多个参数的函数被分解成多个函数,当被串联调用时,这些函数将一次累加一个所需的所有参数。这种技术有助于应用函数式编写的代码更容易浏览和编写。须要留神的是,要实现一个函数,它须要从一个函数开始,而后分解成一系列函数,每个函数承受一个参数。

应用场景:

  • 使代码便于了解 //react-redux,connect 办法,将 component 要用到的 state 切面和 action 注入到它的 property 中,达到 ui 组件,和容器组件拆散的目标。

    let Container=connect(mapStateToProps,mapDispatchToProps)(Component);

  let {Map}=Immutable;

    let obj={
        a:1,
        b:2
    }

    // 克隆出一个
    let map=Map(obj);

    // 调用 immutable 中的 map 对象下的 set 办法来批改指定 key 的 value
    let map1=map.set('a',10);
    let map2=map1.set('a',20);
    
    // 两个对象批改互不影响
    console.log(map1.get('a'),map2.get('a'));  //10,20

判断一个变量是不是数组的有哪几种办法?

  • Object.prototype.toString.call(arg) === ‘[object Array]’ // 目前最精确的办法
  • Array.isArray(arg) // 有兼容性问题,IE8 下不反对
  • arg instanceof Array // 不能跨 iframe 应用
  • arg.constructor===Array // 不能跨 iframe 应用,constructor 能够改写,a.constructor=Object; 会导致判断不精确
// 最通用的办法
var arr = [];
function isArray(str){return Object.prototype.toString.call(str) == "[object Array]";
}

console.log(isArray(arr));//ie 所有版本均反对;

0.1+0.2 为什么不等于 0.3?

浮点数据误差问题,JS 中整数与小数都只有一种类型:Number;

它的实现遵循 IEEE 754 规范,应用 64 位固定长度示意,就是规范的 double 双精度浮点数。

这样存储的存储构造长处:归一化解决整数和小数,节俭存储空间。

64 位比特可分为三个局部:

  • 符号位 S:第 1 位正负数符号位(sign),0 代表负数,1 代表正数;
  • 指数位 E:两头的 11 位存储指数(exponent), 用来示意次方数;
  • 尾数位 M:最初 52 位是尾数(mantissa), 超出的局部主动进一舍零;

数学工式如上图:

4.5 转换过程

  • 比拟 10 进制的 4.5 转换成 2 进制就是 100.1
  • 迷信计数法示意注是(二进制)1.001*2^2
  • 舍去 1 后,M=001;
  • E=1025

如何解决 js 精度计算问题?

类库:

  • Math.js

哪些操作会造成内存透露?

内存透露起因:不再用到的内存,没有及时开释,就叫做内存透露;

  • 全局变量缓存数据(无奈被垃圾回收机制收集)
  • 定时器没有革除
  • 闭包的循环援用
  • js 谬误援用 dom 元素(dom 尽管删除,然而援用还在内存中)

js 垃圾回收机制?

  • 援用计数(如果没有援用指向该对象,对象将被垃圾回收机制回收,毛病:在循环援用的状况下,存在局限性)
  • 标记革除(解决循环援用的问题,和援用计数实质雷同,可达内存被标记,其余的被当作垃圾回收)

null,undefined 区别?别离会在什么状况下呈现?

null: 代表无的状态,此处不应该有值 —(之前没定义这个变量,就是 null)— 作用对象原形的起点

undefined: 代表未找到,短少值 —(之前定义了,却没有赋值就是 undefined)— 变量赋值,函数传参

js 语言的特点?

答:异步,单线程,事件驱动,解释性语言,弱类型;

什么是作用域链?

作用域链就是【变量】和【函数】和可拜访范畴,

管制着变量和函数的可见性与生命周期,在 js 中变量的作用域有全局作用域和部分作用域;

什么是闭包,如何应用,闭包有什么问题?

闭包是由函数创立的一个词法作用域,外面的变量被援用后(内部函数援用,前提得先 return 进去),能够在这个词法环境之外应用;

函数嵌套函数,可能读取【其余函数】外部变量的【函数】;

闭包肯定得 return 能力读取外部的值;

闭包的原理就是作用域链

用处

  1. 创立外部变量,使得这些变量不能随便被内部批改,然而又能够通过指定的函数接口批改
  2. 缩小全局变量
  3. 让这些值始终保持在内存中

闭包的问题:

  • 耗性能:闭包会使函数内的变量始终放弃在内存当中,

解决:在退出函数之前,将不应用的函数变量全副删除;

// 应用自执行函数写法

 // 定义一个闭包
    let secretFn=(function (){
        // 变量 secrent 只有 secretFn 内的 getSecret, setSecret 才能够拜访,内部无法访问
        let secrent='100';
        let getSecret=function (){return secrent;}
        let setSecret=function (newSecrent) {secrent=newSecrent;}
        return {
            getSecret,
            setSecret
        }
    })()


    console.log(secretFn.getSecret());
    secretFn.setSecret(200);
    console.log(secretFn.getSecret());
    console.log(secretFn.secrent);   //Type error 无法访问

// 应用 new 写法

    // 定义一个闭包
    let SecretFn=function (){
        // 变量 secrent 只有 secretFn 内的 getSecret, setSecret 才能够拜访,内部无法访问
        let secrent='100';
        this.getSecret=function (){return secrent;}
        this.setSecret=function (newSecrent) {secrent=newSecrent;}
    }

    const secretOne=new SecretFn();
    console.log(secretOne.getSecret());
    secretOne.setSecret(200);
    console.log(secretOne.getSecret());
   function F() {
        let a = 1
        window.G = function () {console.log(a)
        }
    }
    F()
    G() // 1, G 能拜访到 F 函数的变量,他就是闭包

如何获取闭包函数内的变量?

  1. 函数嵌套,闭包
  2. 函数返回值,return

js 有哪几种数据类型?

js 一共七种类型;

根本类型(6):String,Boolean,Number,Undefined,Null,Symbol(创立惟一的值)

援用类型(1):Object(Function,Array, Date, RegExp)

js 如何判断数据类型?

  1. typeof:不能判断 array,object,function;
  2. instanceof:能够应用 能够用来判断数组;[1] instanceof Array 返回 true
  3. toSring Object.prototype.toString.call([]) 返回 true
  4. constructor [].constructor===Array 返回 true

js 有哪些内置对象?

object 是 js 中所有对象的父对象;

数据关闭类对象:object,array,boolean,number,string

其余对象:function,arguments,math,date,RegExp,error

js 如何实现继承?

  1. 通过原型链(prototype)来实现
  2. 通过构造函数继承 -(把子函数中应用)
  3. es6 的 class, 配合 extend 来实现继承
  4. 拷贝继承(创立一个 extendFun 的办法)

前端路由实现原理?

前端实现路由有两种形式:

1) history 模式

次要借助 html5 的两个 api,

window.history.pushState(“/detail”) // 增加历史记录

window.history.replaceState(“/detail”) // 替换以后历史记录

两个 API 都会操作浏览器的历史记录,而不会引起页面的刷新。

2) hash 模式

实现的 api:

监听哈希变动触发的事件(hashchange) 事件,

window.location 解决哈希的扭转时不会从新渲染页面

性能优化:

如何进行性能优化?

缩小网络申请(大小,数量)— 网络会有提早, 大部分浏览器一性能获取 6 - 8 个申请:

  • 资源合并 / 代码压缩:js, 图片(webP,base64),css
  • 升高 CPU 耗费

    • 缩小 DOM 操作:缓存 DOM 查问,合拼 DOM 插入,事件节流
  • 缓存:放弃名字不变,如果要扭转能够应用 hash 来扭转
  • 减速服务端资源返回的速度:

    • cdn(千牛,bootcdn)
  • 懒加载(次要解决图片,默认图片代码实在图片)
  • SSR 后端渲染

图片懒加载的实现原理?

原理:img src 中放入一张很小的图片,把实在的图片放在 img 的属性中,data-src, 通过监听页面滚动过程中,图片间隔顶部的高度来设置页面是否显示;

个别能够应用

  • jquery.lazyload.js // 到了可视区才加载
  • lazysizes.js // 没有到可视区才显示性能,不依赖 jquery

注意事项:

  • 应用节流函数进行性能优化

如何在 js 中实现不可变对象?

  • 深拷贝,性能十分差,不适宜大规模应用
  • immutable.js,自成一体的一套数据结构,性能良好,然而学习额定的 api
  • immer, 利用 proxy 个性,无需学习额定的 api,性能良好

immutable 实现原理?

原理:长久化数据结构,构造共享,只批改对象树中变动的节点和受它影响的父节点,其它节点共享;

immutable data 就是一旦创立,就不能再被更改的数据。对 immutable 对象的任何批改或增加 / 删除操作都会返回一个新的 immutable 对象。

长处:

  • 升高 mutable 可变对象的复杂度
  • 节俭内存空间(不必深拷贝对象,共享构造,没有被援用的对象会被垃圾回收)
  • 数据回退,任意穿梭(每次数据都是不一样的,只有把这些数据放在一个数组中储存起来,可任意回退)
  • 拥抱函数式编程,关怀数据的映射,命令式编程关怀解决问题的步骤,函数式编程比命令式编程更实用于前端开发。因为只有输出统一,输入必然统一,这样开的组件更易于调试和组装。

毛病

  • 容易与原生对象混

什么是重排什么是重绘?

DOM 的构造属性扭转就会触发重排或者重绘;

只扭转 DOM 节点对象的 css 的色彩,不扭转大小,其余排版属性就属于重绘;

visibility:hidden,暗藏 dom 节点只触发重绘,display:none 暗藏 dom 节点触发重排和重绘;

扭转 padding 会触发: 重排 + 重绘

什么是深拷贝和浅拷贝,如何实现深拷贝?

js 中数据类型分为 2 类,援用数据类型(array,object,function),和其余数据类型(string,number,boolean,null,undefind);

深拷贝指拷贝后的对象与原来的对象互相独立,批改任何一方,其余一方都不受影响;

深拷贝次要有

  1. es6 的 spread 开展,能够深拷贝数组,对象;
  2. for 循环顺次读取复制
  3. 先通过 JSON.stringify 把对象转化成字符串,再通过 JSON.parse 把字符串转换成对象(如果对象中蕴含函数,正则表达式会失落;对象有循环援用会报错;)
  4. 内部库:jquery extend,应用规范库 lodash 的 cloneDeep

注意事项:

Object.assign 只能深拷贝第一层,深层的还是浅拷贝;

深拷贝办法:jquery 的 extend

$.extend([deep],target,object1,object2....)  //deep 不写就是浅拷贝

let phone={​    from:"Apple"}

let phone1={

​    product:"iphone",

​    price:5000

}

let phone2={

​    product:"ipad"

​    price:4000,

}

$.extend(true,obj1,obj2);  // 进行深拷贝,把 obj2 合拼到 obj1 中

$.extend(obj1,obj2);  // 不进行深拷贝

什么是事件节流和函数防抖的区别,和理论使用?

相同点:为了限度函数执行的次数,导致的性能节约;

不同点:

事件节流 throttle:指定工夫周期内,只能执行一次;

使用

  • 滚动到底部触发事件
  • 函数防抖 debounce:指定工夫周期后,能力执行此函数,如果这周期内反复触发,就会从新开始计算
  • 输入框实时搜寻
  • window resize

长列表优化?

思路:虚构列表

  • 只显示局部数据
  • 通过监听滚动条的地位(向上滚动 / 向下)来进行,来进行对数组进行动静替换
  • 顶部应用 padding 来代替

介绍下 PWA,为什么 service worker 能够进步性能 ?

定义:pwa 渐近式增弹网页利用

PWA 特点:

  • 领有桌面入口,可装置
  • 原生利用界面:// 在 manifest 文件中配置,自定义桌面图标 / 导航栏色彩
  • 可离线拜访 , 须要 Https 环境 // 本地环境 localhost 也能够调试
  • 反对 Push 推送
  • 后盾加载,哪怕页面敞开,pwa 依然能够在后盾运行获取数据(有限度)// 哪怕 chrome 敞开

    service worker 是 html5 中的 api,它在 web worker 的根底上加了长久缓存和网络代理能力,联合 cache api 面向提供了 js 来操作浏览器缓存的能力。service worker 接管网页申请,做为中间层;

    service worker 特点:

    • 领有独立的执行线程,独自的作用域范畴,独自的运行环境,有本人独立的 context 上下文。
    • 因为有独立线程,service worker 不能间接操作页面 DOM。但能够通过事件机制来解决,例如应用 postMessage

canvas

canvas 与 svg 区别?

  1. 历史:svg 有十多年历史,并不是 html5 专用标签;
  2. 展现成果:svg 导出后的成果是矢量图形,而 canvas 显示成果是位图(所以 canvas 能够引入图片)
  3. 技术原理:svg(XML 文档)是通过 html 绘制 – 能够应用 DOM 操作,canvas 通过 js 绘制;
  4. canvas 反对色彩较 svg 多;
  5. 应用案例:svg(百度地图),canvas(图表)

canvas 与 webGL 的关系?

canvas 就是一个画布,能够在 canvas 上获取 2D 上下文和 3D 上下文,其中 3D 上下文个别就是 webGL.

webGL 是应用 js 去调用局部封装过的 OpenGL es2.0 标准接口,去提供硬件级别的 3D 图形减速性能。

三都的关系:javascript-> webGL -> OpenGL -> … -> 显卡 并 把最终渲染进去的图形出现在 canvas

webGL 罕用库:

  • three.js // 在浏览器绘制 3D 的 js 库,底层是 webGL (three.js 会对不反对的浏览器做降级计划,应用 casnvas 2D api 解决,有两个 Rennderer ,,webGLRenderer, CanvasRenderer

canvas 罕用库:

  • echarts // 图表(柱状图、饼图、K 线图、雷达图、热力求、关系图、树图、漏斗图、仪表盘、地图),也有应用 webGL 的 3D 图形
  • antV // 阿里开的图形引擎

js 事件

js 事件机制?

javascript 是事件驱动型语言,网页上的任意操作(键盘,鼠标)会产生一个“事件”(event),当事件发现时,能够对事件进行响应,具体如何响应某个事件由事件处理函数实现。

1)事件流

事件流形容的是从页面中承受事件的程序

DOM 事件流的三个阶段:

  • 捕捉阶段:先调用捕捉阶段的处理函数 btn.addEventListen(‘click’),事件从 window 对象自上而下向指标节点流传的阶段;
  • 指标阶段:调用指标阶段的处理函数;
  • 冒泡阶段:调用冒泡阶段的处理函数,事件从指标节点自下而上向 window 对象流传的阶段;

bug 阐明:下图中短少:html 标签

2)DOM 事件级别

DOM 级别分为四级,因为 DOM1 中没有事件相干的内容,即没有 DOM1 级事件,所以 DOM 事件分为 3 个级别,别离是:DOM 0/2/3

  • DOM0:el.onclick=function(){} // <button onclick=”clickBtn()”>btn</button>
  • DOM2: el.addEventListener(eventName,callback,useCapture)
    • click 事件
  • DOM3: 在 DOM2 的根底上,减少更多的事件类型
    • UI 事件:load、scroll
    • 焦点事件:blur、focus
    • 鼠标事件:dbclick、mouseup
    • 键盘事件:keydown、keypress
    • …..
    • 阐明:DOM3 级事件容许使用者自定义一些事件

参考:js 事件原理、事件委托、事件冒泡和事件绑定 addEventListener

3)事件代理

请参考:什么是事件委托 / 事件代理?

4)事件对象

event

  • event.preventDefault() // 阻止默认行为
  • event.stoppropagation() // 阻止事件冒泡
  • event.target & event.currentTarget // 指标对象,target 指向事件真正的收回者,currentTarget 指向监听事件者

5)铺获与冒泡的程序问题

  • 绑定多个 DOM 事件,先注册先执行

参考资料:浏览器事件零碎

什么是事件委托 / 事件代理?

事件委托就是利用 事件冒泡,只指定一个事件处理程序,就能够治理某一类型的所有事件,利用父级去触发子级的事件;

长处:

  • 节俭内存占用,缩小事件注册
  • 新增子对象时,无需再次对其绑定事件,适宜动静增加元素

毛病(局限性):

  • focus,blur 事件自身没有事件冒泡机制,所以无奈委托
  • mousemove,mouseout,须要一直通过地位去计算定位,对性能耗费高,不适宜事件委托
  • 层级过多,冒泡过程中可能被某层阻止掉(倡议就近委托)
<script>
     // jquery 当中的事件委托,反对动静增加的元素
     
     $('#ui').on('click','li',function (event){console.log(event.target.innerHTML);
    })
</script>

跨域

如何解决跨域的问题?

一、CORS: 跨域资源共享,
Access-Contorl-Allow-Origin 后盾设置容许跨域拜访的 url;
应用额定的 HTTP 头通知浏览器,
cors 分类:简略申请,非简略申请;

  • 简略申请:不会触发 cors 预检申请,
  • 非简略申请:

二、通过 jsonp
三、nodejs 中间件代理,在服务端拿到数后,再把数据返回给前端,nginx 代理
四、websocket 协定跨域
五、postMessage, 能够实现多个页面之间的通信(html5 中的一个 api)

jsonp 介绍、原理?

利用 script 标签没有跨域限度,来达到第三方通信的目标,须要后端配合

jsonp 的解释,第三方产生的响应为 json 数据的包装,即 json padding

步骤:

  1. 【发送申请】:发送申请,携带返回数据的包装办法
  2. 【返回数据】后端返回数据,应用 cb 包装数据
  3. 【执行前端办法】前端加载完数据,调用本地曾经封装好的 cb 办法,获取到回调的数据

form 表单能够跨域吗?

能够;

跨域的唯一标准,就是你不能通过申请的形式拿到他人内容;

form 表单只是发申请,而不是获取数据;

ajax 始终在期待他人的 done or fail 这就波及到拿他人数据;

this

bind,call,apply 的区别?

共用点:

  • 扭转函数执行时的上下文,再具体点就是扭转函数运行时 this 的指向
  • 三者第一个参数都是 this 要指向的对象,如果未传入,默认指向全局 window
  • 三者都能够传入参数

不同点:写法不一样

bind: fn.bind(thisArg, 队列 or 数组)()

call: fn.call(thisArg, arg1, arg2,…)

apply: fn.apply(thisArg, [argsArray])

能够做的几个事:

  • 求数组中的最大和最小值;
  • 利用 call 和 apply 做继承

const arr=[1,2,3]

Max.max.apply(null ,arr);

this 的指向问题?

this 是函数运行时所在的环境对象

this 用法的四种状况:

  1. 纯正的函数调用
  2. 作用对象办法的调用
  3. 作为结构函数调用
  4. apply 调用

this 的指向准则:

  1. this 永远指向一个对象
  2. this 指向齐全取决于函数调用的地位

参考:

彻底搞懂 JavaScript 中的 this 指向问题

Javascript 的 this 用法

apply,call 区别?

apply,call 作用都是扭转 this 的指向,只是参数写入的不同

apply 把参数放入一个数组当中;

call 把参数顺次写入;

let params={a:20}

function fun(value1,value2){​     console.log(this.a,value1,value2);

}

//apply,call 性能一样,都是为了扭转 this 的指向,参数的写入形式有不同

fun.apply(params,[11,12]);

fun.call(params,11,12);

API

String api?

属性:

  • 长度:length

办法

  • 增:

    • 前 / 后:+
    • 两头:

      • 索引:先切割(str.slice(startIndex,endIndex)),再拼装
      • 字符(首个,全副):str.replace(new RegExp(targetStr,’g’),targetStr+addStr);
  • 删:
    • 指定字符:replace+ 正则替换为空
    • 指定索引删除:str.slice(startIndex,endIndex)
  • 改:

    • 正则替换
  • 查(遍历):

    • 判断

      • 是否蕴含指定字符串:includes
      • 是否以指定字符串(开始 / 结尾),可指定开始地位:startsWith,endsWith
    • 查问

      • 索引:

        • - 指定索引的字符,chatAt
        • 类数组的形式:str[index]
      • 字符

        • (首次 / 最初一次)呈现的索引:indexOf, lastIndexOf
        • 统计:呈现的总次数, split 分隔后数组长度 -1
        • 返回指定符:substring(反对正数): 两个索引之间
  • 其余操作:

    • 反复:repeat
    • 去除空格(结尾 + 结尾):trim
    • 转成小 / 大字母:toLowerCase/toUpperCase

Array api?

原型办法

  • 办法:

    • Array.from(): 把类数组 / 可迭代对象中创立一个新的数组实例
    • Array.isArray(); // 判断某个变量是否是数组对象
    • Array.of(val1,val2) // 创立数组 , 相当于 [val1,val2]
  • 属性:

    • Array.length: // 不罕用

实例属性:

  • 长度:length

实例办法:

  • 定义:

    • 字面量赋值:let arr=[‘a’
    • 构造函数:let arr=new Array([‘a’]);
  • 减少:

    • 结尾(可反对多个参数):arr.unshift(val1,val2);
    • 尾部:arr.push(‘a’)
    • 两头:

      • 指定索引地位减少:arr.splice(fromIndex,0,val1,val2)
      • 指定元素前面增加:应用 indexOf 找到索引,再能过 arr.splice(fromIndex,0,val1,val2) 遍历增加
  • 删除:

    • 结尾:arr.shift(),返回被删除的元素,扭转原数据
    • 结尾:arr.pop(), 返回被删除的元素,扭转原数组;
    • 两头(对原数组没影响):arr.splice(startIndex,deleteNum,addNewValue) // 在指定索引地位删除元素
  • 批改

    • 索引:arr[0]=’a’
  • 查问:

    • 判断:

      • 是否蕴含:arr.include(‘a’)
      • 满足某个条件:

        • some(有一个满足条件)
        • every(所有都满足条件)
        • findIndex(满足条件的第一个索引)
    • 索引:arr.indexOf(‘a’)
  • 遍历:

    • 不批改原对象:

      • forEach:返回的是通过解决后的数组,长度不变
      • reduce(reduceRight): 可返回任意值,(遍历 -> 解决并返回)
    • 批改原对象:filter ,map
  • 其余:
    • 填充 : arr.fill(value,start,end) 用一个固定值填充一个数组中,从起始索引 (蕴含) 到终止索引(不蕴含)内的全副元素。
    • 元素翻转:arr.reverse(); // 原数组扭转
    • 排序:arr.sort();
    • 连贯:arr.join(‘-‘),依照指定链接符号,把 array 转出一个 string
    • 切割:arr.slice(startIndex,endIndex); startIndex 蕴含,endIndex 不蕴含;// 返回被切割后的数组(对原数组的浅拷贝),不影响原数据
    • 获取对象所有的 keys(Array Iterator 对象): keys,要应用 for(const key of iterator){console.log(key)} 能力查看,间接打印就是一个空的{}

Object Api?

构造函数属性:

  • Object.length // 值为 1
  • Object.prototype // 可为所有 Object 类型对象增加属性

构造函数办法:

实例属性(object.prototype 对象上):

  • constructor:特定函数,用于创建对象的原型
  • proto :(被解冻,禁止批改)指向当对象被实例化的时候,用作原型对象

实例办法:

  • toString:(不罕用)返回对象的字符串示意
  • hasOwnProperty: 判断对象本身属性(非原型链继承),返回 boolean

Function Api?

原型属性(Function):

  • arguments : 以数组模式获取传入函数的所有函数
  • name : 获取函数的名称

实例属性(Function):

  • constructor : 申明函数的原型构造方法

实例办法(Function.prototype):

  • apply
  • bind
  • call

Number Api?

原型 Number(属性):

原型 Number(办法):

  • 判断值是不是 NaN: isNaN
  • 判断是不是有穷数:isFinite
  • 判断是不是整数:isInteger

Math Api?

  • 原型办法(Math):

    • 绝对值:abs(x)
    • 随机数:返回 0 到 1 之间的伪随机数据,random
    • 向上 / 下取整:ceil/floor
    • 次幂:pow(4,3) //4x4x4 等于 4 的 3 次幂

js 全局 函数?

全局属性:

  • 无穷大:Infinity,-Infinity // 正 / 负 无穷大
  • 未定义:undefined
  • NaN

全局函数

  • 解析字符串并返回整数 / 浮点数:parseInt,parseFloat
  • 把对象的值转成数字:Number
  • 把对象的值转成字符串:String
  • 从新运算参数的内容:eval
  • 判断某个值是不是数字:isNaN
  • 判断某个值是否为无穷大:isFinite // 无限的返回 true, 无穷返回 false, NaN 返回 false
  • 编码 / 解码 URI: encodeURI, decodeURI
  • 编码 / 解码 URI:encodeURIComponent, decodeURIComponent

正文完
 0