-
null常用来描述空值,undefined常用来表示变量没有初始化或属性/元素不存在
null==undefined;//true null===undefined;//false
-
JS加载的方式
-
同步:JS本身运行就是同步的
-
defer,只适用于外部脚本文件,告诉浏览器立即下载但延迟执行
-
async,同只适用于外部脚本文件,不让页面等待脚本下载和执行,从而异步加载页面其他内容,JS加载完该脚本文件会立即执行且会在页面load事件前执行,但不能保证脚本会按顺序执行
-
-
JS基本数据类型:String Number Boolean null undefined Symbol(ES6新出的)Object(包括Array)
-
JS判断数据类型的方法
-
typeof 特殊:typeof(null)==='object'//true 是JS很多年了的一个bug
-
instanceof 基于原型链
-
Object.prototype.toString
-
constructor
-
jQuery.type()
-
-
JS中call,bind,apply
-
共同点:都是用来改变this的指向
-
call和apply不同点:两者第一个参数都是this要指向的对象,但后面传入的参数列表,call的可以是任意的,但apply的必须是数组
-
call和bind不同点:call改了this指向后会继续执行函数,bind改过后不能执行函数,会返回一个绑定新this的函数
-
call的应用:翻转字符串,Array.prototype.reverse.call(str.split(''))
-
apply的应用:求极值,Math.max.apply(null,arr)
-
手写bind
Funtion.prototype.bind=function(context){ var self=this; return function(){ return self.apply(context,arguments); } }
-
-
JS区分大小写,HTML不区分,XHTML不区分
-
如何判断NaN,用x==NaN无法判断,NaN和任何值不相等,包括自身
-
可用X!=X来判断
-
或者用isNaN(),参数为NaN或非数字值(字符串或函数)会返回true
-
-
创建对象的方法
-
对象直接量:var obj={}
-
new创建:var obj=new Object();
-
原型创建:Object.prototype
-
Object.create()
-
-
创建对象的模式: https://blog.youkuaiyun.com/weixin_45026432/article/details/105939054
-
继承的多种方法: https://blog.youkuaiyun.com/weixin_45026432/article/details/105944113
-
事件触发三个阶段
-
window往事件触发处传播,遇到注册的捕获事件会触发
-
传播到事件触发时会触发注册的事件
-
从事件触发处往window传播,遇到注册的冒泡事件会触发(相关:事件委托下面)
(但,如果给一个body中子节点同时注册冒泡和捕获,会按注册的顺序触发)
-
-
事件委托
解决“事件处理程序过多”的问题 来源于事件冒泡
(网上大佬的例子:快递可以一个一个人取,但由前台先统一取,然后每个人都去前台那里取会更好)
<ul id="myLinks"> <li id="aaa">aaa</li> <li id="bbb">bbb</li> <li id="ccc">ccc</li> </ul> <script> var list=document.getElementById('myLinks'); EventUtil.addHandler(list,"click",function(event){ event=EventUtil.getEvent(event); var target=EventUtil.getTarget(event); switch(target.id){ case 'aaa': document.title='change aaa'; break; case 'bbb': document.title='change bbb'; break; case 'ccc': document.title='change ccc'; break; } }) </script>
-
函数作用域& 块作用域 https://blog.youkuaiyun.com/weixin_45026432/article/details/105945317
-
提升
-
包括变量和函数在内的所有声明(赋值或其他运行逻辑不会)都会在任何代码被执行前首先被处理
-
每个作用域都会进行提升操作
-
函数声明会被提升,但函数表达式不会提升,即使是具名的函数表达式,名称标识符在赋值前也无法在所在作用域中使用
var foo=function bar(){}//foo和bar在这行代码前都无法调用
-
-
闭包 https://blog.youkuaiyun.com/weixin_45026432/article/details/105946405
-
如何找出类关系
-
a instanceof Foo
在a的整条原型链中是否有指向Foo.prototype
的对象 -
Foo.prototype.isPrototypeOf(a)
a的整条原型链中是否出现过Foo.prototype
-
Object.getPrototypeOf(a)===Foo.prototype
ES5中用 -
a.__proto__===Foo.prototype
ES6前非标准,绝大多数浏览器支持
-
-
关于this https://blog.youkuaiyun.com/weixin_45026432/article/details/105947151
-
Promise
在这之前用的是回调来实现需求,但回调会把控制权交给第三方,有可能会带来一系列控制问题和信任问题,也有可能出现不受欢迎的回调地狱
而Promise就是为了不把继续回调控制权交给第三方,而是希望第三方给我们提供了解任务何时结束的能力,然后自己代码来决定下一步
创建:
new Promise(..)
构造器,必须提供至少一个函数回调,可提供两个函数回调其中的状态有三个术语:resolve决议、fulfill完成、reject拒绝
第一个回调通常用于标识Promise已完成,第二个标识被拒绝
但!第一个回调实际上的结果可能是完成或拒绝,但第一个参数回调的行为和resolve一样,故回调的第一个名称基本都是resolve,第二个都是reject
var promise = new Promise(function(resolve, reject) { if (..){ resolve(value); } else { reject(error); } }); promise.then(function(value) { // 成功 }, function(value) { // 失败 }).catch(function(error){..})
.then和.catch
.then([用于完成回调],[用于拒绝回调])
默认拒绝函数只是将错误重新抛出,错误可以沿着promise链传播下去直到遇到显式定义的拒绝处理函数
默认完成函数只是将接受到的任何传入值传给下一个promise
.catch([拒绝回调函数])
等价于.then(null,..)
一些其他API
-
Promise.all(..)
用于并行执行多个任务Promise.all([p1,p2]).then(function(){..})
以数组形式同时发送多个ajax,返回的主promise在且仅在所有成员promise都完成后才会完成,若有任何一个被拒绝,则主promise立即被拒绝,并丢弃结果
-
Promise.race([..])
只响应第一个完成的Promise,其他均拒绝且丢弃 -
Promise.none([..])
和all情况相反,只有所有成员都被拒绝后才完成 -
Promise.first([..])
只要完成第一个,就会忽略后续的任何拒绝和完成 -
Promise.last([..])
只有最后完成的一个胜出
-
-
const let var
const:用于创建常量,必须要有显式的初始化(
undefined
必须是const a = undefined
),常量不是对值本身的限制,而是对赋值的那个变量的限制,故若该值是复杂值,仍可改变(const a=[1,2,3]; a.push(4);
)此时的a不持有一个常量数组,持有的是一个指向数组的常量引用let:
let
允许声明一个作用域被限制在块级中的变量、语句或者表达式,且是在编译时才初始化var:
var
声明的变量只能是全局或者整个函数块的 -
箭头函数
-
箭头函数总是函数表达式,不存在箭头函数声明,是匿名函数表达式,故没有用于递归/事件绑定的命名引用
-
只有在表达式短时用才有足够的好处,长时无需用
-
只有在函数体表达式个数大于1时或函数体包含非表达式时才用{}
var f1=()=>12; var f2=x=>x*2;
-
主要设计目的是改变this的行为特性,在箭头函数中,this的绑定不是动态的,而是可预测的
带来的优势:
var con={ make:function(..){ var self=this; btn.addEventListener("click",function(){..},false);//在这里面需要用到this时,需要从外面绑定 } } 改: var con={ make:function(..){ btn.addEventListener("click",()=>{..},false);//此时用了箭头函数就不需要另外绑定 //此时this会和当前函数指向相同的值 } }
带来的劣势:
var con={ make:(..)=>{ //.. this.helper(); }, helper:(..)=>{..}; } //此时的this不会指向con,this是从包围的作用域中继承来的,故this指向全局作用域
-