JS基础、重点和难点

一、JS基础

  1. js引入:<script>alert('111')</script>,<script language="javascript" src="myJs.js"></script>

  2. 注释:单行注释   //   ,多行注释     /* 注释 */

  3. 数据类型以及转化:

       简单数据类型:string、number、boolean、null、undefined、symbol(ES6新增)

      复杂数据类型:object

      typeof:NaN 的数据类型是 number,NaN不等于任何值,包括它本身,null 的数据类型是 object,数组(Array)的数据类型是 object

      instanceof :判断对象的原型链,({})  instanceof Array // false,([])  instanceof Array // true    ([]) instanceof Object//true

      Number() :原始类型:字符串如果不可以被解析为数值,返回 NaN,null转为数值时为0,undefined:转成 NaN;对象:                              valueof=》tostring=》number(),参数是对象时,将返回NaN,除非是包含单个数值的数组,parseInt('1234abc') // 1234,parseFloat('0256.25.35') // 256.25

      String():原始类型:原值的字符串;对象:"[object Object]";数组:数组的字符串形式,与Number的调用顺序相反                                    tostring=》valueof=》string() 

      Boolean():空数组([])和空对象({})对应的布尔值,都是true,Boolean(NaN) // false

                        Boolean(Infinity) // true

      0.1 + 0.2 !== 0.3//由于浮点数不是精确的数值,js需要转成二进制计算,0.000110011……由于存储空间有限,最后计算机会舍弃后面的数字,所以我们最后就只能得到一个近似值,确实需要计算的话用Math.abs(a-b)<Number.EPSILON来表示是否相等,Number.EPSILON为2^-52

0 / 0 // NaN

      parseInt的参数不是字符串,则会先转为字符串再转换,字符串转为整数的时候,是一个个字符依次转换,如果遇到不能转为        数字的字符,就不再进行下去,number则是一次性,isNaN('Hello') // true相当于isNaN(Number('Hello')) // true

特殊例子:null == undefined、undefined != 0、null != 0、null !== undefined

  4. 字符窜:length属性,字符串拼接ES6的eg:  `${name}`,常用方法:

​​​         concat():用于连接两个或多个字符串

         indexOf()​​​​:返回某个指定的子字符串在字符串中第一次出现的位置,从0开始,大小写敏感,没找到返回-1

         match():返回所有查找的关键字内容的数组,没有的话返回null,eg:"To be or not to be".match(/to/ig)返回["To", "to"]

        search(): 返回模式第一个匹配的位置索引,如果没找到则返回-1

        replace():用一些字符替换另一些字符,或替换一个与正则表达式匹配的子串,第一个参数为regexp或者字符串,第二个参数表示替换的字符

        slice():返回提取的子字符串;只有1个参数,返回参数下标到结尾处的所有字符串,两个参数a,b则提取[a,b),substring()方法类似

        substr():第一个参数为开始位置,第二个参数表示返回的子字符串数量

        split():把字符串分割成字符串数组,第一个参数表示分隔符,第二个参数表示返回数组的最大长度

        toString():转换为一个字符串,并返回结果

        trim() :用于删除字符串的头尾空格,不会改变原始字符串

        startsWith()、endsWith()、includes()、toLocaleLowerCase()和 toLocaleUpperCase()

  5. 数组遍历以及数组的其他方法: 

       检测是否是数组:Array.isArray()   

    ①for   in  :for(let key in arr) {console.log(arr[key]);}

    ②foreach 不会改变元素,不会返回新数组:arr.foreach((value,index)=>{})

    ③map遍历数组,对每个元素进行处理,返回一个新数组:let arr2 = arr.map((value,index)=>{value++ return value})

    ④some遍历数组,在回调里进行判断,返回 true 或 false ,当有一个元素满足条件时就停止遍历并返回true;当全部的元素都          不满足要求时,返回false:let bool = arr.some((value,index)=>{return value>3})

    ⑤every遍历数组,当有一个元素不满足条件时就停止遍历并返回false;当全部元素都满足时,返回true

    ⑥filter遍历数组,在回调函数里进行条件判断,当结果为true时,将该元素返回,组成一个新数组

    ⑦reduce(callback(total, currentValue, currentIndex, arr),init)  init为初始值,可以省略,(上一个归并值、当前项、当前项的索引和数组本身)
     every、filter、forEach、map、some传给每个方法的函数接收 3 个参数:数组元素、元素索引和数组本身,都不改变调用它们的数组

    数组的其他方法:

       push:末端添加一个或多个元素,并返回添加新元素后的数组长度

       pop:删除数组的最后一个元素,并返回该元素

       shift:删除数组的第一个元素,并返回该元素

       unshift:在数组的第一个位置添加元素,并返回添加新元素后的数组长度

       join(符号):[1,2,3,4].join(' | ') //  '1 | 2 | 3 | 4'

       concat:['hello'].concat(['world'])// ["hello", "world"]返回一个新数组,原数组不变,如果传入一个或多个数组,则 concat()会把这些数组的每一项都添加到结果数组。 如果参数不是数组,则直接把它们添加到结果数组末尾

       reverse:颠倒排列数组元素,返回改变后的数组,会改变原始数组

       slice(start,end):提取目标数组的一部分,不包含结束索引对应的元素,返回一个新数组,原数组不变,可以将类似数组的对象转为真正的数组例如                                              arguments对象,let arr = Array.prototype.slice.call(arrayLike);

       splice(index,num,item1,..,itemX):用于删除原数组的一些成员,并可以在删除的位置添加新成员,返回值是被删除的元素(数组)

       sort:默认按照字典顺序排序,可以接收一个比较函数,[10111, 1101, 111].sort(function (a, b) {return a - b;})

        indexOf()、lastIndexOf():返回数组下标或者-1,includes()返回Boolean值

        find():返回对象或者undefined

        findIndex():返回数组下标或者-1

  6. 对象:相当于一张散列表

      访问:obj.xxx或者obj['xxx']

      释放对象内存:delete  obj.xxx;

      对象数据属性:要修改属性的默认特性,就必须使用 Object.defineProperty(对象,属性的名称,描述符对象)方法,多个属性可用Object.defineProperties(obj,{})

                [[Configurable]]:是否可通过delete删除属性

                [[Enumerable]]:是否可通过for in返回

                [[Writable]]:是否可以修改属性值

                [[Value]]:属性值

        对象访问器属性:访问器属性不包含数据值

                [[Configurable]]:是否可通过delete删除属性

                [[Enumerable]]:是否可通过for in返回

                [[Get]]:获取函数

                [[Set]]:设置函数

        获取属性方法:Object.getOwnPropertyDescriptor(obj,key),

                                Object.getOwnPropertyDescriptors(obj)

        对象解构赋值:const { a: anotherNameA, b: anotherNameB = 123 } = obj

  7. 对象遍历

     keys(): 返回数组的索引(结果为数组),包括对象自身的(不含继承的)所有可枚举属性(不含Symbol属性),先以升序枚举数值键,然后以插入顺序枚举字符串和符号键

    values(): 返回数组的元素(结果为数组)

    entries(): 返回数组的索引/值对(结果为二维数组)

     ②for  in  :循环遍历对象自身的和继承的可枚举属性(不含Symbol属性)

  8. ||:将会返回第一个不是false的值 或者最后一个值(如果全部都是FALSE的话),不一定是bool值

  9. 函数

arguments参数:可以访问所有该函数的传入值,例如n个,arguments是类数组对象(但不是 Array 的实例),箭头函数没有arguments

function abc() {
    for(let i=0; i< arguments.length; i++) {
        window.alert(arguments[i]);
    }
}

ECMAScript 中的所有参数都按值传递的。不可能按引用传递参数。如果把对象作 为参数传递,那么传递的值就是这个对象的引用

在标准函数中,this 引用的是把函数当成方法调用的上下文对象

在箭头函数中,this引用的是定义箭头函数的上下文

  10. 函数中传入值还是地址的区别:第一个输出还是900没变,第二个改变了,因为传入地址导致堆的原数据改变了

        

  11. 防止鼠标右键拷贝:<body οncοntextmenu="return false"></body> 

      防止用户选中内容用ctrl+c复制:<body onselectstart="return false"></body> 

  12. DOM

        属性:nodeType,nodeName,nodeValue,childNodes,parentNode,previousSibling,nextSibling

       document对象 :title属性(显示在浏览器标签)

             getElementById():id选择器

             getElementByClassName():类选择器

             getElementsByName():通过name获取,主要用于checkbox

             getElementsByTagName():通过标签名获取             

             createElement(标签名):动态的创建一个节点

             appendchild(节点名):(要在节点里添加内容才能显示)添加节点到一个已知的节点下作为子节点,在这个节点的childNodes的末尾加入,返回值为这个节点

             removeChild(节点名):删除一个元素,需要先知道父元素,可以用                                                         xxx.parentNode.removeChild(xxx)

              insertBefore(新节点,参照节点):参照节点为null则功能和appendChild一样

              replaceChild(新节点,被替换节点):       

       element:其中class属性用className获取,innerHtml、innerText、focus()、blur()

                createElement(标签名):创建元素

                getAttribute(属性名):访问style属性时返回css字符窜,而用element.style返回对象,访                                                     问事件属性返回一段js代码,而用element.事件返回一个函数

                setAttribute(属性名,属性值):多用于设置自定义属性

                removeAttribute(属性名):彻底删除该属性(包括属性值)

             querySelector('.myclass'):通过各种选择器返回匹配的第一个节点

             querySelectorAll('#app'):返回nodelist(快照,不是实时的)

             classList属性:主要用于删除某个类名,例如div.classList.remove("disabled")

             dataset属性:

<div id="myDiv" data-appId="12345" data-myname="Nicholas"></div>

let div = document.getElementById("myDiv");
// 取得自定义数据属性的值
let myName = div.dataset.myname;
// 设置自定义数据属性的值
div.dataset.myname = "Michael"; 

             innerHTML:返回元素里面的html字符窜,可读可写

             outerHTML:返回包含该元素的html字符窜,可读可写

             style属性:元素的样式,myDiv.style.backgroundColor = "red",特别的float写cssFloat,                          style的cssText属性可以直接读和写样式,removeProperty(属性名),                                          setProperty(propertyName, value, priority),priority可以是'important'

             scrollIntoView方法:div.scrollIntoView({behavior: 'smooth', block: 'start'});

        尺寸:

                offsetHeight:包括padding、border、水平滚动条、content

                clientHeight:包括padding、content

                offsetTop:元素上边框外侧距离最近父元素上边框内侧

                scrollHeight:没有滚动条出现时,元素内容的总高度

                scrollLeft:内容区左侧隐藏的像素数,设置这个属性可以改变元素的滚动位置。

                scrollTop:包含border-top,没有滚动条时为0

                getBoundingClientRect():该方法获取元素的left、top、right、bottom、height 和 width

  13. 正则表达式RegExp:

        隐式创建:let reg = /正则表达式/gi,显式创建:let reg = new RegExp(正则表达式,“gi”);g表示全局,i表示忽略大小写

        exec():检索想要找的内容,结果返回一个数组,第一个值为找到的文本内容,找不到时返回null

        属性:index、lastindex、leftContext、rightContext

        元字符限定符:{n}表示出现次数,{n,m}表示最少出现n次最多m次,满足贪婪匹配,即尽可能的匹配更多的字符串,+表            示出现1次以上,*表示出现0次及以上,?表示0到1次

        字符匹配符:[a-z]表示小写字母a-z,[A-Z],[0-9],[^a-z]匹配不是a-z中的任意一个字符

        

        定位符:^表示匹配目标字符串的开始位置,$表示匹配目标字符串结束位置

  14. 声明函数的办法:函数的声明function(){},函数表达式(末尾加‘;’),只有函数声明会提升

        函数执行时所在的作用域,是定义时的作用域,而不是调用时所在的作用域

        function(a, b, ...rest) {}:rest表示剩余的参数

  15.Json常用方法:转为字符串Json.stringify(),转为对象Json.parse() 

  16.ES6新增内容:

      Map:与对象类似,但是可以用复杂类型做key,

      Set:似于数组,但是成员的值都是唯一的,没有重复

      结构赋值:let { bar,foo } = { foo: "aaa", bar: "bbb" },let [x, y = 'b'] = ['a']; // x='a', y='b'

  17. 运算符:

      “+”:字符串相连接,运算子是对象,必须先转成原始类型的值,然后再相加,首先valueOf,再toString(特例Date对象的实        例,那么会优先执行toString)

      “比较运算符”:字符串按照字典顺序(Unicode )进行比较,如果两个运算子都是原始类型的值,则是先转成数值再比较,如         果运算子是对象,会转为原始类型的值,再进行比较,两个复合类型(对象、数组、函数)比较时,比较它们是否指向同一         个地址。undefined和null与其他类型的值比较时,结果都为false,它们互相比较相等时结果为true。

        

  18. 事件

事件流:捕获阶段(window到目标)、到达目标、冒泡阶段,focus和blur不会冒泡

        e.stopPropagation():事件停止传播,e.preventDefault:取消浏览器的默认行为

addEventListener(事件名,处理函数,布尔值):布尔值true表示在捕获阶段触发

removeEventListener:好用的浏览器兼容库(add-dom-event-listener)

模拟事件:document.createEvent(事件类型),UIEvents、MouseEvents、HTMLEvents

eg:

let btn = document.getElementById("myBtn");
// 创建 event 对象
let event = document.createEvent("MouseEvents");
// 初始化 event 对象
event.initMouseEvent("click", true, true, document.defaultView,
 0, 0, 0, 0, 0, false, false, false, false, 0, null);
// 触发事件
btn.dispatchEvent(event)

19.Bom

window:用var定义一个全局变量会挂载在window上,而用let或者const则不会,常用方法:                 window.scrollTo({ left: 100, top: 100, behavior: 'smooth' }),                                                              window.open(url,'_blank',"height=400,width=400,top=10,left=10,resizable=yes")

location:location.href="http://xxxxx",search属性用来获取query参数,location.replace(),                          location.reload(true):true表示不适用浏览器缓存

navigator:一般用userAgent属性来判断什么客户端,                                                                                         geolocation.getCurrentPosition(fun1,errFun)获得地理位置,                                                           onLine判断浏览器是否连网

history:history.go(x),x为负数表示后退,length属性表示页面栈

二、JS难点

  1. 变量提升:先解析代码,获取所有被声明的变量,提升变量,但是没有提升赋值,函数提升优先于变量提升,且不会被变量声明覆盖,但是会被变量赋值之后覆盖
       console.log(a);var a=1;//输出undefined,但是不会报错  ===var a;console.log(a);a=1;

  2. 原型链:

         
     每个函数都有prototype,指向原型对象(Person prototype),原型对象自动获得一个名为 constructor 的属性指回与之关联的构 造函数,每个对象实例都有一个_proto_指向创建该对象的构造函数的原型,所有原型的原型为Object函数的原型,最终源头为null

返回原型对象:Object.getPrototypeOf(实例obj)

重写一个对象的原型继承关系:Object.setPrototypeOf(a,b),a链到b(一般不用)

实例自己本身是否拥有改属性:obj.hasOwnProperty(key)

只要给对象实例添加一个属性,这个属性就会遮蔽原型对象上的同名属性,使用 delete 操作符可以完全删除实例上的这个属性

in操作符:key in obj (key是否在obj的原型链上)

function Person() {}
Person.prototype = {
 name: "Nicholas",
 age: 29,
 job: "Software Engineer",
 sayName() {
 console.log(this.name);
 },
 // constructor: Person // 手动将constructor指向Person,这时候的[[Enumerable]]为true
}; 

 // 恢复 constructor 属性
Object.defineProperty(Person.prototype, "constructor", {
 enumerable: false,
 value: Person
})

以上例子的Person.prototype的constructor就不再指向Person了,而是指向Object

先重构Person.prototype再new实例和先new实例再重构Person.prototype是不一样的

先new实例

  3. 异步操作:异步任务的写法通常是回调函数。一旦异步任务重新进入主线程,就会执行对应的回调函数

     promise:状态有未完成、完成(成功、失败),变化:①未完成=>成功,返回一个value;②未完成=>失败,抛出一个error

                    promise.all([请求1,请求2]).then() :用于不同url的两个请求 

     async、await:async  function xxx(){ await  ajax请求}

  4. 深、浅拷贝,直接赋值

    浅拷贝:Object.assign({},{name: 'ljh'})或者let a= {age: 5}; let b = {...a}

    深拷贝:对象中还有对象,用JSON.parse(JSON.stringify(obj))

    大致解析图:

                  

当我们把一个对象赋值给一个新的变量时,赋的其实是该对象的在栈中的地址,而不是堆中的数据。也就是两个对象指向的是同一个存储空间,无论哪个对象发生改变,其实都是改变的存储空间的内容,因此,两个对象是联动的。

浅拷贝是按位拷贝对象,它会创建一个新对象,这个对象有着原始对象属性值的一份精确拷贝。如果属性是基本类型,拷贝的就是基本类型的值,改变某一个不会影响另外一个的值;如果属性是内存地址(引用类型),拷贝的就是内存地址 ,因此如果其中一个对象改变了这个地址,就会影响到另一个对象。即默认拷贝构造函数只是对对象进行浅拷贝复制(逐个成员依次拷贝),即只复制对象空间而不复制资源

  5. 防抖和节流

    防抖:将多次执行变为最后一次执行,在n秒内只能执行一次,如果在n秒内触发了事件则重新计算时间,eg防止重复点击某个按钮、滚动条滚动

function debounce(fn,delay){
    let timer = null //借助闭包
    return function() {
        if(timer){
            clearTimeout(timer) 
        }
        timer = setTimeout(fn,delay) // 简化写法
    }
}

    节流:连续触发事件,但在n秒内只执行一次,将多次执行变成每隔一段时间执行,例如输入框关键字搜索

function throttle(fn,delay){
    let valid = true
    return function() {
       if(!valid){
           //休息时间 暂不接客
           return false 
       }
       // 工作时间,执行函数并且在间隔期内把状态位设为无效
        valid = false
        setTimeout(() => {
            fn()
            valid = true;
        }, delay)
    }
}

  6. class

        构造函数里的属性和方法会变成实例的属性和方法,普通方法会挂载在类的原型上,而静态方法则只有类自己使用

class Person {
 constructor() {
 // 添加到 this 的所有内容都会存在于不同的实例上
 this.locate = () => console.log('instance', this);
 }
 // 定义在类的原型对象上
 locate() {
 console.log('prototype', this);
 }
 // 定义在类本身上
 static locate() {
 console.log('class', this);
 }
}
let p = new Person();
p.locate(); // instance, Person {}
Person.prototype.locate(); // prototype, {constructor: ... }
Person.locate(); // class, class Person {}

    new的过程:类实例化时传入的参数会用作构造函数的参数

  1. 新生成了一个对象
  2. 链接到原型(对象的_proto_指向构造函数对象的prototype)
  3. 绑定 this(this 指向新对象)
  4. 返回新对象(如果构造函数返回非空对象,则返回它)   
function Foo() {
    return this;
}
Foo.getName = function () {
    console.log('1');
};
Foo.prototype.getName = function () {
    console.log('2');
};

new Foo.getName();   // -> 1
new Foo().getName(); // -> 2

   new Foo() 的优先级大于 new Foo,对于第一个函数来说,先执行了 Foo.getName() ,所以结果为 1;对于后者来说,先执 行 new Foo() 产生了一个实例,然后通过原型链找到了 Foo 上的 getName 函数,所以结果为 2

继承:extends,类和函数都可以继承

派生类的方法可以通过 super 关键字引用它们的原型, 只能在派生类构造函数和静态方法中使用,react中经常可见,不能在调用 super()之前引用 this。

        super(); // 相当于 super.constructor()

  7. this:

function foo() {
	console.log(this.a)
}
var a = 1
foo()

var obj = {
	a: 2,
	foo: foo
}
obj.foo()

// 以上两者情况 `this` 只依赖于调用函数前的对象,优先级是第二个情况大于第一个情况

// 以下情况是优先级最高的,`this` 只会绑定在 `c` 上,不会被任何方式修改 `this` 指向
var c = new foo()
c.a = 3
console.log(c.a)

// 还有种就是利用 call,apply,bind 改变 this,这个优先级仅次于 new

  8. 闭包:指引用了另一个函数作用域中变量的函数 ,A 返回了一个函数 B,并且函数 B 中使用了函数 A 的变量,函数 B 就被称为闭包

function A() {
  let a = 1
  function B() {
      console.log(a)
  }
  return B
}

闭包会保留它们包含函数的作用域,所以比其他函数更占用内存

  9. 模块化:AMD(RequireJS)、CMD(SeaJS)、CommonJs、ES6

      AMD:通过define()函数定义,第一个参数是一个数组,里面定义一些需要依赖的包,第二个参数是一个回调函数,通过变量                    来引用模块里面的方法,最后通过return来输出

     CMD:define()定义,没有依赖前置,通过require加载插件,即插即用

     CommonJs:module.exports={}或者exports.xxx=...,前端浏览器里面并不支持module.exports,一般是node.js后端使用的

     ES6:export/import
  10. 对象的创建方式

      ①工厂模式:用函数来封装创建对象的细节,在函数里面创建对象并返回对象

      ②构造函数模式:给构造函数传递不同的参数,利用new来创建不同实例

      ③原型模式:用Person.prototype.xxx=‘a’来定义原型的属性,之后用new创建实例,一旦原型属性改变,所有实例属性也改变

      ④混合构造函数和原型模式:构造函数定义私有属性,原型定义共有属性和方法

      ⑤动态原型模式 、寄生构造函数模式、稳妥构造函数模式

  11. 继承

       父类(继承谁,提供继承的属性)
  

      ①原型链继承:让新实例的原型等于父类的实例

   

        特点:实例可继承的属性有:实例的构造函数的属性,父类构造函数属性,父类原型的属性

        缺点:新实例无法向父类构造函数传参,继承单一,所有新实例都会共享父类原型的属性

      ②构造函数继承:用.call()和.apply()将父类构造函数引入子类函数(在子类函数中做了父类函数的自执行)

        

       特点:继承父类构造函数的属性没有继承父类原型的属性,可继承多个构造函数属性(call),在子实例中可向父实例传参

       缺点:只能继承父类构造函数的属性,无法实现构造函数的复用,每个新实例都有父类构造函数的副本,臃肿

      ③组合继承(原型链继承和借用构造函数继承):结合了两种模式的优点,传参和复用

        

       特点:可以继承父类原型上的属性,可以传参,可复用,每个新实例引入的构造函数属性是私有的

       缺点:调用了两次父类构造函数(耗内存),子类的构造函数会代替原型上的那个父类构造函数

      ④原型式继承、寄生式继承、寄生组合式继承

        

        

        

  12. call、bind、apply

     call和apply都可以解决this指向,区别是第二个参数call接收的是一个列表而apply接收一个数组,call 方法第一个参数是要绑定给this的值,后面传入的是一个参数列表,当第一个参数为null、undefined的时候,默认指向window。apply接受两个参数,第一个参数是要绑定给this的值,第二个参数是一个参数数组。当第一个参数为null、undefined的时候,默认指向window。

let a = {
    value: 1
}
function getValue(name, age) {
    console.log(name)
    console.log(age)
    console.log(this.value)
}
getValue.call(a, 'yck', '24')
getValue.apply(a, ['yck', '24'])

      bind的第一个参数是this的指向,从第二个参数开始是接收的参数列表。区别在于bind方法返回值是函数以及bind接收的参数列表的使用。、

var obj = {
    name: 'Dot'
}
function printName() {
    console.log(this.name)
}
var dot = printName.bind(obj)
console.log(dot) // function () { … }
dot()  // Dot



function fn(a, b, c) {
    console.log(a, b, c);
}
var fn1 = fn.bind(null, 'Dot');

fn('A', 'B', 'C');            // A B C
fn1('A', 'B', 'C');           // Dot A B
fn1('B', 'C');                // Dot B C
fn.call(null, 'Dot');      // Dot undefined undefined

13.模块化:

CommonJS:exports 和 require

var moduleB = require('./moduleB');
module.exports = {
 stuff: moduleB.doStuff();
}; 

AMD:define

define('moduleA', ['require', 'exports'], function(require, exports) {
 var moduleB = require('moduleB');
 exports.stuff = moduleB.doStuff();
}); 

ES6:export 和 import,as重命名,default默认导出只能一个,一个文件可以有多个export

import和require的区别:

模块加载时间:require是运行时加载,而import是编译时加载,并且会提升到整个模块头部

模块本质:require模块就是对象,输入时必须查找对象属性,import的模块不是对象,而是通过 export 命令显式指定输出的代码

// CommonJS模块
let { exists, readFile } = require('fs');
// 等同于
let fs = require('fs');
let exists = fs.exists;
let readfile = fs.readfile;

// ES6模块 import { exists, readFile } from 'fs';

严格模式:CommonJs模块默认采用非严格模式,ES6 的模块自动采用严格模式,CommonJS 模块输出的是一个值的拷贝,ES6 模块输出的是值的引用

14.Map和Set

Map:与object类似,但是可以用任意类型作为键,长度属性size

const newMap = new Map([[key: 'value']]),传入一个二维数组

方法:set(key, value),get(key),has(key),set()方法返回映射实例,可以把多个操作连缀起来,

           delete(key)和 clear()

Set:const s1 = new Set(["val1", "val2", "val3"]),传入数组,长度属性size

方法:add(value),has(value),delete(value), clear(),add()方法返回映射实例,可以把多个操作连缀        起来,集合直接转成数组const array = [...set]

15、异步函数和Promise

promise:new Promise((resolve,reject) => {...})

Promise.all([]):按照数组排序返回结果数组,只要有一个reject,就进入catch,返回最先reject的请求错误

Promise.race():返回最先结束pending状态的请求,无论reject还是resolve

async:用于声明异步函数,函数里有return的话就是期约,没有的话就是普通函数

await:暂停异步函数代码的执行,让出 JavaScript 运行时的执行线程,必须在异步函数里使用,              也就是在async函数里

用异步函数可产生一个sleep函数

16、动画和canvas

requestAnimationFrame(function):接收一个要在重绘屏幕前调用的函数,返回一个请求 ID

cancelAnimationFrame(动画id)

canvas:getContext('2d')获取上下文引用

               toDataURL("image/png"):canvas转成图片

                填充和描边

let context = drawing.getContext("2d");
 context.strokeStyle = "red";
 context.fillStyle = "#0000ff";

17、跨文档消息XDM:在不同执行上下文(如不 同工作线程或不同源的页面)间传递信息的能力

postMessage(message,目标接收源),接收到 XDM 消息后,window 对象上会触发 message 事件

18、元素拖动

dragstart-drag-dragend   dragenter-dragover-drop

19、错误处理

try { return 2; } catch (error){ console.log(error.message) return 1; } finally { return 0; }

抛出错误:throw new Error("process(): Argument must be an array.");

20、网络请求

最初的请求XMLHttpRequest:

let xhr = new XMLHttpRequest();
xhr.open("get", "example.txt", false);
xhr.send(null); 

请求体中FormData类型:let data = new FormData(); data.append("name", "Nicholas");

跨源资源共享(CORS):协议、域名、端口三者之间任意一个与当前页面url不同

         解决方法:1、JSONP;

                        2、服务器端设置Access-Control-Allow-Origin;

                        3、如果带cookie前端还要axios.defaults.withCredentials = true

                        4、fetch()

                        5、如果是本地开发,可以用webpack本地代理

                        6、Nginx反向代理

Web Socket:

let socket = new WebSocket("ws://www.example.com/server.php");
let stringData = "Hello world!";
let arrayBufferData = Uint8Array.from(['f', 'o', 'o']);
let blobData = new Blob(['f', 'o', 'o']);
socket.send(stringData);
socket.send(arrayBufferData.buffer);
socket.send(blobData); 
socket.close();

socket.onmessage = function(event) {
 let data = event.data;
 // 对数据执行某些操作
};
socket.onopen = function() {
 alert("Connection established.");
};
socket.onerror = function() {
 alert("Connection error.");
};
socket.onclose = function() {
 alert("Connection closed.");
}; 

21、客户端存储

cookie:document.cookie = cookieText(可采取js cookie库辅助,目前用的较少)

storage:sessionStorage(会话级)、localstorage(永久),都是同步操作可马上读,每当                             Storage 对象发生变化时,都会在文档上触发 storage 事件

        getItem()、setItem()、removeItem()、clear()

  • 2
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值