Giter Club home page Giter Club logo

laoergege-blog's Introduction

Hi there 👋

laoergege-blog's People

Contributors

alexanderbelokon avatar atinux avatar azrikahar avatar barbapapazes avatar bdrtsky avatar benjamincanac avatar clemcode avatar cogor avatar danielroe avatar davestewart avatar debs-obrien avatar farnabaz avatar geminii avatar harlan-zw avatar jefrydco avatar kevinmarrec avatar laoergege avatar mannil avatar mathe42 avatar maximepvrt avatar nobkd avatar nozomuikuta avatar pi0 avatar qwertovsky avatar renovate-bot avatar renovate[bot] avatar tahul avatar thomorlo avatar utamori avatar yuki-inoue avatar

Stargazers

 avatar  avatar

Watchers

 avatar

laoergege-blog's Issues

Set、WeakSet、Map、WeakMap

  • Set
    • 类似集合、成员不能重复
    • 可以存储任意类型数据
    • size、add、delete、has、clear
    • 可以遍历,keys、values、entries、forEach
  • WeakSet
    • 跟 Set 类似,但成员只能是引用类型
    • 成员都是弱引用
    • 无法遍历
  • Map
    • 字典、[key => value] 储存结构
    • key、value 可以任意类型
    • size、set、get、delete、has、clear
    • 可以遍历,keys、values、entries、forEach
  • WeakMap
    • 跟 Map 类似,但 key 只能是引用类型
    • 键名是弱引用
    • 无法遍历

弱引用,即不会增加该对象引用计数

如果你想辅助存储数据,又不想干扰垃圾回收机制,就可以使用 WeakMap、WeakSet。

遍历

Set、Map:

keys():返回键名的遍历器。
values():返回键值的遍历器。
entries():返回所有成员的遍历器。
forEach():遍历 Map 的所有成员。

迭代器模式

for(let t of map) {
    console.log(t)
}

更多详细
Set 和 Map 数据结构

排序算法

const nums = [1, 0, 4, 3, 5, -6, 7, 8, 12, 10]

function bubbelSort(nums) {
    for(let i = nums.length - 1; i > 0; i--) {
        for(let j = 0; j <= i; j++) {
            if(nums[j] > nums[j + 1]) {
                let tmp = nums[j]
                nums[j] = nums[j + 1]
                nums[j + 1] = tmp
            }
        }
    }
    return nums
}

console.log('bubbelSort', bubbelSort(nums))

function selectionSort(nums){

    for(let i = 0; i < nums.length; i++) {
        let min = i
        for(let j = i + 1; j < nums.length; j++) {
            if(nums[min] > nums[j]) {
                min = j
            }
        }

        let tmp = nums[i]
        nums[i] = nums[min]
        nums[min] = tmp
    }

    return nums
}

console.log('selectionSort', selectionSort(nums))


function insertionSort(nums){
    for(let i = 1; i < nums.length; i++) {
        let tmp = nums[i]
        let j = i - 1
        while(j >=0 && tmp < nums[j]) {
            nums[i--] = nums[j--]
        }
        nums[i] = tmp
    }
    return nums
}

console.log('insertionSort', insertionSort(nums))

function quickSort(arr, left, right) {
    if(left >= right) return arr

    const index = partition(arr, left, right)
    quickSort(arr, left, index - 1)
    quickSort(arr, index + 1, right)
    return arr
}

function partition(arr, left, right) {
    let pivot = right;
    let counter = left;
    for(let i = left; i <= right; i++) {
       if(arr[i] < arr[pivot]) {
           [arr[counter], arr[i]] = [arr[i], arr[counter]]
           counter++;
       } 
    }
    [arr[counter], arr[pivot]] = [arr[pivot], arr[counter]]

    return counter
}

console.log('quickSort', quickSort(nums, 0, nums.length - 1))

function mergeSort(nums) {
    if (nums.length <= 1) return nums;
    let mid = Math.floor(nums.length/2);
    let left = nums.slice(0, mid);
    let right = nums.slice(mid);
    return merge(mergeSort(left), mergeSort(right))
}

function merge(left, right) {
    const result = []
    let i = 0, j = 0
    while(i < left.length && j < right.length) {
        result.push(left[i] < right[j] ? left[i++] : right[j++])
    }

    while(i < left.length) {
        result.push(left[i++])
    }

     while(j < right.length) {
        result.push(right[j++])
    }

    return result
}

console.log('mergeSort', mergeSort(nums))

运算符优先级

题目1

new Cls().x //(new Cls()).x
new new Cls() // new (new Cls())
new Cls.x() // (new (Cls.x)())

作用域链及闭包

闭包形成的本质:词法作用域 + 函数是一等公民

词法作用域 ,就是按照源码指定的词法位置划分作用域,JavaScript 作用域分为

  • 全局作用域
  • 函数作用域
  • 块作用域

当前作用域变量查找不到时就会往外层作用域查找,依次类推,形成的查找链路就是作用域链

根据词法作用域,内部函数可以访问外部的变量

如果仅仅是词法作用域,那么嵌套函数调用关系可以用调用栈去表示并且根据调用栈去查找变量

但是 JavaScript 中函数是一等公民,函数也可以作为变量赋值,意味着函数可以在其他外部作用域被调用

根据词法作用域原则,当外部函数被销毁,需要将内部函数引用到的外部作用域变量保留下来,跟该函数关联起来,以便引擎执行该函数代码能够继续查找到原词法位置中外部的变量,这样就形成了闭包

闭包就是外部作用域变量的集合

在 JavaScript 中,被保存引用在函数的作用域链,跟该函数关联起来

题目

var fn = null
const foo = () => {
    var a = 2
    function innerFoo() { 
        console.log(c)   // undefined         
        console.log(a) // 2
    }
    fn = innerFoo
}

const bar = () => {
    var c = 100
    fn()    
}

foo()
bar()

技巧:做这些题目分析的时候,不用管函数被传到在哪里执行,只需要在原词法位置进行分析就行

get和post有什么区别

  • 请求参数
    • get 跟在 url 后面以 & 符号连接
    • post body 里
  • 参数长度
    • get 浏览器限制
    • post 没有
  • 参数编码,GET请求只能进行url编码,而POST支持多种编码方式
  • 相对的安全性,get是将参数通过url传递的,会被浏览器缓存,容易被他人获取,post相对来说,比较安全。
  • 请求缓存:get请求会被缓存,而post请求不会,除非手动设置。

this 指向

  • this 指向
    • 默认情况下普通函数执行上下文中的 this 是指向全局对象 window 的,但在严格模式下,this 值则是 undefined
    • 对象调用
    • call、bind、apply 调用
    • 构造函数(this 指向新创建的对象)
    • 箭头函数(执行上下文没有 this,依靠作用域链继承外层作用域的 this)

经典面试题目

// 嵌套函数中的 this 不会从外层函数中继承
var myObj = {
  name : "极客时间", 
  showThis: function(){
    console.log(this) // myObj
    function bar(){console.log(this)} // window
    bar()
  }
}
myObj.showThis()

// 缓存 this
// 把 this 体系转换为了作用域的体系,通过作用域链去继承
var myObj = {
  name : "极客时间", 
  showThis: function(){
    console.log(this)
    var self = this
    function bar(){
      self.name = "极客邦"
    }
    bar()
  }
}
myObj.showThis()
console.log(myObj.name)
console.log(window.name)

// 箭头函数
// ES6 中的箭头函数其自身的执行上下文没有 this,所以箭头函数中的 this 取决于它的外部函数。
var myObj = {
  name : "极客时间", 
  showThis: function(){
    console.log(this)
    var bar = ()=>{
      this.name = "极客邦"
      console.log(this)
    }
    bar()
  }
}
myObj.showThis()
console.log(myObj.name)
console.log(window.name)

手写 call、apply、bind 实现

  • call、apply 调用目标函数并改变其 this 指向
    • fun.call(thisArg, arg1, arg2, ...) 第二参数起为参数列表
    • func.apply(thisArg, [argsArray]) 第二参数为参数数组或者类数组
  • bind 返回一个新函数,其 this 绑定目标对象
    • 调用新函数时,将给定参数列表作为新函数的参数序列的前若干项
    • new 调用时,忽略绑定的对象
var obj = {
    value: 1
}

function bar(name, age) {
    return {
        value: this.value,
        name: name,
        age: age
    }
}

Function.prototype.call2 = function(context) {
    var _context = typeof context === 'undefined' ?  window : context
    _context.fn = this

    var args = []
    for (let i = 1; i < arguments.length; i++) {
        args.push('arguments[' + i + ']')
    }

    var result = eval('_context.fn(' + args + ')') // array.toString [1, 2, 3] => '1,2,3'

    delete _context.fn
    return result
}

console.log('call2', bar.call2(obj, 'lys', 1))

Function.prototype.apply2 = function(context, arr) {
   var _context = typeof context === 'undefined' ?  window : context
    _context.fn = this

    var args = []
    for (let i = 0; i < arr.length; i++) {
        args.push('arr[' + i + ']')
    }

    var result = eval('_context.fn(' + args + ')') // array.toString [1, 2, 3] => '1,2,3'

    delete _context.fn
    return result
}

console.log('apply2', bar.apply2(obj, ['lys', 1]))

Function.prototype.bind2 = function(context) {
    var fn = this
    var args = Array.prototype.slice.call(arguments, 1)
    var wrapper = function () {
        var _args = args.concat(Array.prototype.slice.call(arguments)) // 调用新函数时,将给定 bind 后面的参数列表作为新函数的参数序列的前若干项
        
        if(this instanceof fn) { // new 调用时,忽略 bind 指定的 context
            fn.apply(this, _args)
            return this
        } else {
            return fn.apply(context, _args)
        }
    }
    wrapper.prototype = fn.prototype // new 调用时,将原型为绑定原函数的原型

    return wrapper
}

console.log(bar.bind2(obj)('lys', 1))

console.log(bar.bind2(obj, 'lys')(1))

console.log(new (bar.bind2(obj, 'lys'))(1)) // . 优先级比 new 高

apply 的一些妙用:使用 apply 巧妙得将参数列表的函数支持参数数组

1、Math.max。用它来获取数组中最大的一项 Math.max.apply(null, nums)
2、类数组方法借用,实现两个数组合并 Array.prototype.push.apply(arr1, arr2)

手写节流、防抖

  • 防抖(防止重复执行)
    • 事件触发 n 秒后再执行,如果期间再次触发则重新计算时间,最终只会执行一次
    • 思路:每次触发事件时都取消之前的延时任务
  • 节流(减少函数的执行频率)
    • 高频事件触发,每隔n秒执行一次,所以节流会稀释函数的执行频率
    • 思路
      1. 判断当前时间是否达到可执行
      2. 判断是否有待执行任务 (setTimeout 版本)
function debounce(fn, delay) {
    let timer;

    return function(...res) {
        clearTimeout(timer)

        timer = setTimeout(fn.bind(this, ...res), delay)
    }
}

// const t = debounce((e) => {console.log(e)}, 1000)
// t(123)
// t(456)

// 持续触发事件,每隔一段时间,只执行一次事件。
// 时间戳版本
function throttle(fn, time){
    let start = Date.now()
    return function(...res) {
        let cur = Date.now()

        if(cur - start >= time) {
            fn.apply(this, res)
            start = Date.now()
        }
    }
}

// 定时器版本
// function throttle(fn, time){
//     let timer;
//     return function(...res) {
//         if(timer) {
//             return 
//         }

//         timer = setTimeout(() => {
//             fn.apply(this, res)
//             timer = null
//         }, time)
//     }
// }


const t = throttle(() => {console.log(123)}, 1000)

setInterval(t, 500)

模板字符串实现

let a = {
    b: 'ppp'
}

function template(tmp) {
    return tmp.replace(/\{.+?\}/g, (match) => {
        return (new Function('return ' + match.slice(1, -1)))() || match
    })
}

template('hello,{a.b}123{a.c}')

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.