美文网首页
原生JS相关

原生JS相关

作者: zhenghongmo | 来源:发表于2019-12-06 17:42 被阅读0次

1.ES6语法

  • let const 箭头函数 Promise 展开操作符 默认参数 import export

2.Promise、Promise.all、Promise.race 分别怎么用

  • Promise 用法
function fn(){
  return new Promise((resolve, reject) => {
      成功时调用 resolve(数据)
      失败时调用 reject(错误)
  })
}

fn().then(success, fail).then(success1, fail1)
  • Promise.all 用法
Promise.all([promise1, promise2]).then(success1, fail1)
只有 promise1 和 promise2 都成功才会调用success1
  • Promise.race用法
Promise.race([promise1, promise2]).then(success1, fail1)
promise1 和 promise2 只要有一个成功就会调用success1

3. 手写函数防抖和函数节流

  • 防抖
    一段时间会等,然后带着一起做了
function delays (fn, delay){
  let timerId = null
  return function (){
      const context = this
      if(timeId){ 
          window.clearTimeout(timeId) 
      }
      timeId = setTimeout(() => {
          fn.apply(context, arguments)
          timeId = null
      }, delay)
  }
}
const delayed = delays(() => {console.log("lalalla")})
delayed() 
delayed()
  • 节流
    一段时间执行一次后,就不执行第二次了
function throttle(fn, delay){
  let canUse = true
  retuen function() {
      function() {
        if(canUse){
            fn.apply(this,arguments)
            canUse = false
            setTimeout(() => {
                canUse = true
            }, delay)
        }
      }
  }
}
const throttled = throttle(() => {console.log("lskllsl")})
throttled()
throttled()

4.手写AJAX

var request = new XMLHttpRequest()
request.open('GET', 'a/b/c?name=mm', true)
request.onreadystatechange = function () {
  if(request.readyState === 4 && request.status === 200) {
    console.log(request.responseText)
  }
}
request.send() //post请求body放在这里面

5.this问题

this 就是你 call 一个函数时,传入的第一个参数(this 就是 call 的第一个参数 fn.call(this, n1,n2))

  • fn()
    this => window/global
  • obj.fn()
    this => obj
  • fn.call(xx, arguments)
    this => xx
  • fn.apply(xx)
    this => xx
  • fn.bind(xx)
    this => xx
  • new Fn()
    this => 新的对象
  • fn = () => {}
    this => 外面的this
    this

6. 闭包

闭包

函数调用了函数之外的变量

!function () {
  //两个闭包 函数+变量
  var lives = 50
  window.addlive = function () {
    lives += 1
  }
  window.dielive = function () {
      lives -=1
  }
}()
  • 内存泄漏:你用不到(访问不到)的变量,依然占据着内存空间,不能被再次利用起来。闭包不会造成内存泄漏

7. 立即执行函数

立即执行函数:声明一个匿名函数,马上调用这个匿名函数

  • 写法
(function(){alert('我是匿名函数')} ()) // 用括号把整个表达式包起来
(function(){alert('我是匿名函数')}) () //用括号把函数包起来
!function(){alert('我是匿名函数')}() // 求反,我们不在意值是多少,只想通过语法检查。
+function(){alert('我是匿名函数')}()
-function(){alert('我是匿名函数')}()
~function(){alert('我是匿名函数')}()
void function(){alert('我是匿名函数')}()
new function(){alert('我是匿名函数')}()

创建一个独立的作用域
这个作用域里面的变量,外面访问不到(避免变量污染)

var liList = ul.getElementsByTagName('li')
for(var i=0; i<6; i++){
  liList[i].onclick = function(){
    alert(i) // 为什么 alert 出来的总是 6,而不是 0、1、2、3、4、5
  }
}

---------用立即执行函数给每个 li 创造一个独立作用域,在立即执行函数执行的时候,i 的值被赋值给 ii,此后 ii 的值一直不变--------

var liList = ul.getElementsByTagName('li')
for(var i=0; i<6; i++){
  !function(ii){
    liList[ii].onclick = function(){
      alert(ii) // 0、1、2、3、4、5
    }
  }(i)
}

8.JSONP、 CORS 、跨域?

JSONP

  • 同源策略:浏览器处于安全方面的考虑,只允许与同域下的接口交互

  • 同域:
    1.同协议: 如都是http或都是https
    2.同域名: 如都是baidu.com/a和baidu.com/b (用户打开baidu.com/a,当前页面下的js向baidu.com/b的接口发ajax请求,浏览器是允许的。但假如想jianshu.com/b发ajax请求就会被浏览器阻止,因为存在跨域调用)
    3. 同端口: 如都是80端口

  • JSONP(创建动态JavaScript)
    通过 script 标签加载数据的方式去获取数据当做 JS 代码来执行。
    提前在页面上声明一个函数,函数名通过接口传参的方式传给后台,后台解析到函数名后在原始数据上「包裹」这个函数名,发送给前端。换句话说,JSONP 需要对应接口的后端的配合才能实现。

<script>
function yyy(ret){
console.log(ret);
}
</script>
<script src="api.xxx.com/weather?callbackName=yyy"></script>
--------------------------------------------------------------------------------------------------
这个请求到达后端后,后端会去解析callback这个参数获取到字符串yyy,在发送数据做如下处理:
之前后端返回数据: {"city": "hangzhou", "weather": "晴天"}
现在后端返回数据: yyy({"city": "hangzhou", "weather": "晴天"})
前端script标签在加载数据后会把 「yyy({"city": "hangzhou", "weather": "晴天"})」做为 js 来执行,
这实际上就是调用yyy这个函数,同时参数是 {"city": "hangzhou", "weather": "晴天"}。
  • 突破同源策略 === 跨域
  • CORS跨域(加响应头)
    response.setHeader('Access-Control-Allow-Origin', 'http://xxx.com:8001')

9. async/await怎么用,如何捕获异常?

async函数

  • promise
function fn() {
  return new Promise ( (resolve, reject) => {
    setTimeout(() => {
      let n = parseInt(Math.random()*6 + 1)  //[0-1)*6+1后取整
      resolve(n)
    },3000)
  })
}

fn() .then( 
//成功调用resolve()
(x) => {
  console.log(x) //这里的x就是上面的n
},
//失败调用reject()
() => {
  console.log(失败) 
}
)
  • await只能放在async函数里面, await命令后面是一个 Promise 对象,返回该对象的结果
  • async可以声明一个异步函数, 返回一个Promise 对象
  • 把异步代码写成同步代码。
function fn(params) {
  return new Promise ( (resolve, reject) => {
    setTimeout(() => {
      let n = parseInt(Math.random()*6 + 1)  //[0-1)*6+1后取整
      if(n>3){
          if(params==="大"){
            resolve(n)
          }else{
            reject(n)
          }
        }else{
           if(params==="小"){
            resolve(n)
          }else{
            reject(n)
          }
        }
    },3000)
  })
}

async function test() {
    try{
        let n = await  Promise.all([fn("大"), fn("小")])
        console.log(n)
    }catch(error){              //捕获reject()
        console.log(error)
    }
}
let result = test ()
console.log(result) //打印出一个Promise

10. 如何实现深拷贝?

  • json实现深拷贝
var a = {...}
var b = JSON.parse(JSON.stringify(a))

缺点:JSON 不支持函数、引用、undefined、RegExp、Date……

  • 递归拷贝
 function clone(object){
     var object2
     if(! (object instanceof Object) ){
         return object
     }else if(object instanceof Array){
         object2 = []
     }else if(object instanceof Function){
         object2 = eval(object.toString())
     }else if(object instanceof Object){
         object2 = {}
     }
     你也可以把 Array Function Object 都当做 Object 来看待,参考 https://juejin.im/post/587dab348d6d810058d87a0a
     for(let key in object){
         object2[key] = clone(object[key])
     }
     return object2
 }

11.JS数据类型

  • string number bool undefined null object symbol
  • object 包括了数组、函数、正则、日期等对象

12. 如何用正则实现 string.trim()

function trim(string){
    return string.replace(/^\s+|\s+$/g, ' ')
}

13. 如何实现数组去重?

  • 计数排序
 var a = [4,2,5,6,3,4,5]
 var hashTab = {}
 for(let i=0; i<a.length;i++){
     if(a[i] in hashTab){
         // 什么也不做
     }else{
         hashTab[ a[i] ] = true
     }
 }
 //hashTab: {4: true, 2: true, 5: true, 6:true, 3: true}
 console.log(Object.keys(hashTab)) // ['4','2','5','6','3']
  • Set去重
    • Set对象允许存储任何类型的唯一值,无论是原始值或者是对象引用
      Array.from()方法就是将一个类数组对象或者可遍历对象转换成一个真正的数组
let  a = [4,2,5,6,3,4,5]
let  b = new Set(a) //返回Set对象 {4, 2, 5, 5, 4, 3}
//将Set对象转化成数组
Array.from(b)   //方法一
[...b]   //方法二
  • 使用 WeakMap???

14. JS原型

原型链

  • 举例
var a = [1, 2, 3]
只有0, 1, 2, length 4个key
为什么可以a.push(4) , push是哪来的?
a.__proto__ === Array.prototype
push就是沿着a.__proto__ 找到的,也就是Array.prototype.push
Array.prototype还有很多方法,如join、pop、slice、splice
//join(): 将数组的元素组起一个字符串,console.log(a.join("-")); // 1-2-3
//pop():数组末尾移除最后一项,减少数组的 length 值,然后返回移除的项。
//slice():返回从原数组中指定开始下标到结束下标之间的项组成的新数组,在只有一个参数的情况下, slice()方法返回从该参数指定位置开始到当前数组末尾的所有项。如果有两个参数
//splice():(1)指定 2 个参数:要删除的第一项的位置和要删除的项数。例如, splice(0,2)会删除数组中的前两项。(2)提供 3 个参数:起始位置、 0(要删除的项数)和要插入的项。例如:splice(2,0,4,6)会从当前数组的位置 2 开始插入4和6。splice (2,1,4,6)会删除当前数组位置 2 的项,然后再从位置 2 开始插入4和6。
Array.prototype就是a的原型(__proto__)

15. 继承

  • 不用class
function Animal() {
  this.body = 'body'
}
Animal.prototype.move  = function() {}
function Human (name){
    Animal.apply(this, arguments)
    this.name = name
}

//Human.prototype.__proto__ = Animal.prototype//非法

var f = function () {}
f.prototype = Animal.prototype
Human.prototype = new f()
Human.prototype.useTools = function() {}
var mm = new Human()
  • 使用class
class Animal{
    constructor() {
        this.body = 'body'
    },
    move() {}
}
class Human extends Animal{
  constructor(name){
      super()
      this.name = name
  },
useTools() {}
}
let mm = new Human()

16.手写promise

promise

手写promise

相关文章

  • 原生JS相关

    1.ES6语法 let const 箭头函数 Promise 展开操作符 默认参数 import export 2...

  • 原生JS继承相关概念

    原型链继承 借用构造函数(经典继承) 缺点 :每次new (实例化)都会重现创建一次 组合继承 (结合原型链继承和...

  • JS与App WebView交互

    采用WebViewBridge做完原生WebView与JS的交互桥梁,下面是相关框架地址: Android:htt...

  • DOM 的一些增删改查

    以下是JS中DOM节点中增删改查的基本API: 查 增 删 改 学习参考:原生JS中CSS相关API合集

  • 20、jQuery 事件机制

    20、jQuery 事件机制 原生js事件与jQuery事件: (1)用原生的js给div注册事件 原生js注册相...

  • 原生js的DOM相关操作

    获取节点 获取父节点: parentNode 获取兄弟节点:nextElementSibling || ne...

  • JS小技巧

    ** 1、 生成随机颜色 ** **2、 原生js获取相关参数 ** **3、横竖屏刷新页面 ** 4、判断是否为...

  • 原生js和jQuery中鼠标,元素位置的区别

    原生js中的相关属性及方法 1.鼠标位置相关 (e为事件对象) ①.鼠标距离 整个文档(0,0)的距离 e.pag...

  • WKWebView与原生代码交互

    原生代码调用js js调用原生代码 注册Handler WKScriptMessageHandler 协议 use...

  • 01-JQuery入口函数

    JQuery入口函数 JS原生入口函数特点原生JS会等到DOM元素加载完毕,并且图片也加载完毕才会执行原生的JS如...

网友评论

      本文标题:原生JS相关

      本文链接:https://www.haomeiwen.com/subject/pedlgctx.html