前端基础知识学习(二)

161 阅读1分钟

1. 100*100的 canvas 占多少内存?

没有思路 参考思路: 100*100个像素点 每个像素点用RGBA四位表示。。。

2.实现数组的filter方法

filter 用法:arr.filter(function(item,index,arr){})

    Array.prototype.myfilter =  function(func) {
        let arr = this;
        let resultarr =[]
        for(let i=0;i<arr.length;i++){
            let item = arr[i];
            let result = func.call(this,item,i,arr)
            if(result){
                resultarr.push(arr[i]) 
            }
        }
        return  resultarr
    }

正确答案

Array.prototype.filter = function(fn,context){
    if(typeof fn != 'function'){
        throw new TypeError(`${fn} is not a function`)
    }
    let arr = this;
    let reuslt = []
    for(var i = 0;i < arr.length; i++){
        let temp= fn.call(context,arr[i],i,arr);
        if(temp){
            result.push(arr[i]);
        }
    }
    return result
}

filter完整用法 array.filter(function(currentValue,index,arr), context)

3.实现数组的flat方法

var newArray = arr.flat([depth]); 手写实现

Array.prototype.myflat = function(deepth =1 ){
    let arr = this;
    let resultarr =[]
    resultarr = arr.reduce((pre,next)=>{
        return pre.concat(next)
    },[])
    return deepth>1? resultarr.myflat(--deepth):resultarr
}

4.数组乱序

思考:

  1. 排序 大小随机。
 arr.sort(()=>{Math.random()-0.5})
  1. 洗牌算法:
// 著名的Fisher–Yates shuffle 洗牌算法.每次随机取一个放到最尾处
function shuffle(arr){
  let m = arr.length;
  while(m > 1){
      let index = parseInt(Math.random() * m--);
      [arr[index],arr[m]] = [arr[m],arr[index]];
  }
  return arr;
}

5. 实现一个模版引擎

  let template = '我是{{name}},年龄{{age}},性别{{sex}}';
  let data = {
    name: '姓名',
    age: 18
  }
  render(template, data); // 我是姓名,年龄18,性别undefined

function render(template, data) {
   return template.replace(new RegExp('{{(.*?)}}', 'g'), (match, key) => data[key.trim()]);
}

6. 实现一个最基本的数据绑定

题意:

  var obj = {
      key_1: 1,
      key_2: 2
  }
  function func(key) {
       console.log(key + ' 的值发生改变:' + this[key]);
  }
  
  //实现一个方法,可以给 obj 所有的属性添加动态绑定事件,当属性值发生变化时会触发事
  testfunc(obj,func)
  obj.key_1 = 2; // 此时自动输出 "key_1 的值发生改变:2"
  obj.key_2 = 1; // 此时自动输出 "key_2 的值发生改变:1"

通过使用Object.defineProperty(obj,key,desc)直接在一个对象上定义一个新属性,或者修改一个已经存在的属性。 let testfunc = (obj,func)=>{ for(let k in obj){ Object.defineProperty(obj,k,{ set:function(newValue){ if(this.value !=newValue){ this.value = newValue func.call(obj,k) } }, get:function(){ return this.value } }) } }

7.转化为驼峰命名 【get-element-by-id】

let f=(str)=>{
    //正则替换
    let s =  str.replace(/-\w/g,(x)=>{
        return x.slice(1).toUpperCase()
    })
    return s
}
//驼峰改回-
let f=(str)=>{
    let s =  str.replace(/[A-Z]/g,(x)=>{
        return '-'+x.toLowerCase()
    })
    return s
}
//笨方法
let func = (str)=>{
    let s = str.split('-')
    let result=''
    for(let i = 0;i<s.length;i++){
        let item =s[i]
        if(i!=0){
            item =item.replace(item[0], item[0].toUpperCase())
        }
        result += item
    }
    return result
}

8. 解析 URL Params 为对象

let getParams= (url) =>{
    let s =url.indexOf('?')==-1? url: url.split('?')[1];
    let arr = s.split('&');
    let obj={}
    for(let i=0;i<arr.length;i++){
        let item = arr[i];
        obj[item.split('=')[0]] = item.split('=')[1]
    }
    return obj
}

9.vue 组件之间的传值通信

三种传值类型:父传子、子传父、兄弟组件之间的通讯 父组件可以使用props向子组件传递数据。子组件通过$emit触发事件,回调给父组件。中央事件总线Bus

10.Proxy 相比于 defineProperty 的优势

Object.defineProperty() 的问题主要有三个:

不能监听数组的变化 必须遍历对象的每个属性 必须深层遍历嵌套的对象

Proxy 在 ES2015 规范中被正式加入,它有以下几个特点:

针对对象:针对整个对象,而不是对象的某个属性,所以也就不需要对 keys 进行遍历。这解决了上述 Object.defineProperty() 第二个问题 支持数组:Proxy 不需要对数组的方法进行重载,省去了众多 hack,减少代码量等于减少了维护成本,而且标准的就是最好的。

除了上述两点之外,Proxy 还拥有以下优势:

Proxy 的第二个参数可以有 13 种拦截方法,这比起 Object.defineProperty() 要更加丰富 Proxy 作为新标准受到浏览器厂商的重点关注和性能优化,相比之下 Object.defineProperty() 是一个已有的老方法。