博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
js 基础要点
阅读量:6550 次
发布时间:2019-06-24

本文共 4382 字,大约阅读时间需要 14 分钟。

对象转基本类型

//Symbol.toPrimitive的优先级最高let a = {    valueOf(){        return 0;    },    toString(){        return '1';    },    [Symbol.toPrimitive](){        return 2;    }}1+a // =>3 '1' + a //=>'12'复制代码

四则运算符

1 + '1' //'11'2 * '2' //4[1,2] + [2, 1] //'1,22,1'//[1,2].toString() ->'1,2'//[2,1].toString() ->'2,1'//'1,2' + '2,1' = '1,22,1''a' + + 'b'  //->"aNaN"//+ 'b' --->NaN//+ '1' ->1复制代码

== 操作符

[] == ![] // -> true 解析如下//[] 转成true ,然后取反变成 false [] == false 则 [] == ToNumber(false)则 [] == 0 则 ToPrimitive([]) == 0//[].toString() ->''则 '' == 0则 0 == 0   ---> true 复制代码

闭包

定义:函数A返回一个函数B,并且函数B中使用了函数A的变量,则函数B就被称为闭包

function A(){    let a = 1    function B(){        console.log(a)    }    return B }复制代码
经典面试题:循环中使用闭包解决var定义函数的问题for( var i=1;i<=5; i++ ){    setTimeout( function timer() {        console.log( i );    }, i*1000);}由于setTimeout 是个异步函数,所以会先把循环全部执行完毕,这时 i 是6了;所以会输出一堆的6 复制代码
解决方法:* 1.使用闭包for (var i = 1; i <=5 ;i++ ){   ( function(j){        setTimeout(function timer() {            console.log(j);        }, j * 1000);    })(i)}* 2.使用setTimeout的第三个参数for (var i = 1; i <= 5; i++){    setTimeout(function timer(j){        console.log(j)    }, i*1000, i);}* 3.使用 let定义 i for (let i = 1; i <= 5; i++ ){     setTimeout( function timer(){         console.log( i );     },i*1000); }复制代码

深浅拷贝

let  a = {    age : 1}let b = a a.age = 2 console.log(b.age) //2 即 若给一个变量赋值一个对象,那么两者的值会是同一个引用,其中一方改变,另一方也会相应的改变。复制代码

解决以上问题方式如下:

浅拷贝: Object.assign 或 展开运算符 (浅拷贝只能解决第一层问题)

let a = {    age : 1}let b = Object.assign({}, a) 或 let b = {...a}a.age = 2 console.log( b.age)   //1复制代码

深拷贝 JSON.parse(JSON.stringify(object)

let a = {    age : 1,    jobs: {        first:'FE'    }}let b = JSON.parse(JSON.stringify(a)a.jobs.first = 'native'console.log(b.jobs.first) //FE
复制代码

![](https://user-gold-cdn.xitu.io/2019/1/1

模板化 在右Babel的情况下,可用直接使用ES6的模板化 commonJS是node独有的规范

防抖

在滚动事件中需要做一个复杂计算或者 实现一个按钮的方二次点击操作。

(频繁的事件回调中做复杂计算,很可能造成页面卡顿,所以不如将多次计算合并为一次计算,只在一个精确点做操作)

ps:防抖和节流 的作用是防止函数多次调用;区别:假设一个用户一直触发这个函数,且每次触发函数的间隔小于wait,防抖的情况下只会调用一次,而节流的情况 会每隔一定时间(参数wait)调用函数。

const debounce = (func, wait = 50) =>{ //缓存 一个定时器id let timer = 0 // return function(...args) { if(timer) clearTimeout(timer) timer = setTimeout(() =>{ func.apply(this, args) },wait) }}复制代码
  • 搜索时,用户输入完最后一个字才调用查询接口, 延迟执行的 防抖函数
  • 点赞 如star是,立马反馈是否star成功,使用立即执行的防抖函数
function debounce (func ,wait = 50 ,immediate = true){    let timer, context,args;    const later = () =>setTimeOut(() => {        timer = null         if(!immediate){            func.apply(context,args)            context = args = null        }    },wait)        return function(...params) {        if(!timer){            timer =  later()            if(immediate){                func.apply(this,params)            }else{                context = this                args = params            }        }else{            clearTimeout(timer)            timer = later()        }    }}复制代码

总结:

  • 对于按钮放点击来说的实现:如果函数是立即执行的,就立即调用,如果函数是延迟执行的,就缓存上下文和参数,放到延迟函数中去执行。一旦我开始一个定时器,只要我定时器还在,你每次点击我都重新计时。 一旦你点累,定时器时间到,定时器重置为null,就可以再次点击了。
  • 对于延迟执行函数来说的实现:清除定时器id,如果是延迟调用就调用函数

节流

节流和防抖动的本质是不一样的。防抖动是 多次执行变成最后一次执行,节流是将多次执行变成每隔一段时间执行。

继承

class MyDate extend Date{    test(){        rreturn this.getTime()    }}let myDate = new MyDate()myDate.test()复制代码

需要用Babel来编译代码 底层限制:若不是Date构造出来的实例,就不能调用Date的函数

function MyData(){    }MyData.prototype.test = function(){    retrun this.getTime()}let d = new Date()Object.setPrototypeOf(d,MyData.prototype)Object.setPrototypeOf(MyData.prototype,Date.prototype)即先创建父类实例 =》 改变实例原先的_proto_转而连接到子类的prototype=》子类的prototype的 _proto_改为父类的prototype通过这种方式实现的继承可以完美解决 JS底层限制复制代码

call ,apply ,bind区别

call和apply: 都是为了解决改变this的指向,只是传参的方式不同。 除了第一个参数外,call可以接收一个参数列表, apply只接受一个参数数组。 bind:作用也是解决改变this的指向,只是该方法返回一个函数。

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'])复制代码

Promise 实现

Promise是Es6 新增的语法,解决了回调地狱的问题 看成一个状态机: 初始pending,通过函数resolve 和reject 将状态改成了 resolved和 rejected 状态,并且状态一旦改变就不能再次变化

then函数会返回一个Promise实例,并且该返回值是一个新的实例而不是之前的实例。因为Promise规范规定处理pending状态,其他状态是不可以改变的, 所以then本质上可以看成是 flatMap

Generator实现

Generator是ES6中新增的语法,都可以异步编程。

function* test(){    let a = 1+2;    yield 2;    yield 3;}let b = test();console.log(b.next()复制代码

转载于:https://juejin.im/post/5c369b6051882524a1414f71

你可能感兴趣的文章
JQuery学习思维导图版
查看>>
maven+spring4+hibernate4 搭建
查看>>
Redis和Memcached的选择
查看>>
servlet,RMI,webservice之间的区别--zhuan tie
查看>>
Lua程序设计--类型与值
查看>>
centos7 gitlab安装
查看>>
hibernate中lazy的使用
查看>>
android jni的JNINativeMethod
查看>>
PHP 获取网页301真实地址
查看>>
免安装的Tomcat基本配置和安装
查看>>
iis配置运行php
查看>>
Eclipse断点调试
查看>>
基于zookeeper实现的分布式锁
查看>>
feign client 开发环境中只调用自己本地的服务
查看>>
VIM复制粘贴大全
查看>>
dpi 、 dip 、分辨率、屏幕尺寸、px、density 关系以及换算
查看>>
json_decode($json,true)和 json_decode($json)的区别
查看>>
分布式任务分发框架Gearman教程和PHP实现实例
查看>>
php rdkafka扩展发送和接收消息
查看>>
WebGIS--ArcGIS for Flex系列开发五:IIS部署
查看>>