JavaScript30练习笔记

很早之前就star了JavaScript30这个项目,却一直没有认真看看(就跟保存在收藏夹的大部分技术文章一样)。最近正在思考如何组织JavaScript代码的问题,决定先从阅读源码开始。下面整理从这个项目中收获到的包括语言特性和代码组织的一些东西。

<!--more-->

参考:

1. JavaScript Drum kit

const keys = Array.from(document.querySelectorAll('.key'));
keys.forEach(key => key.addEventListener('transitionend', removeTransition));

这里直接将NodeList转换为了数组,而我之前的做法是使用Array.prototype.forEach.apply,或者是之间使用for循环,相比之下,Array.from这种写法更加合适,参考MDN文档

以前从已知数组创建新的数组使用的基本都是forEachmap,而Array.from可以从类数组对象中创建新的对象,使用更加灵活。

不过貌似querySelectorAll返回的节点列表自带forEach方法,虽然并不是instanceOf数组的。

2. Scoped CSS Variables and JS

发现作者习惯将事件绑定和事件处理函数分开书写,这样这个代码看起来比较整洁,而我之前在使用jQuery的时候,往往喜欢事件绑定和事件处理函数写在一起,整个文件都充斥着这样的逻辑代码,看起来很冗杂。这点需要改进。

此外这里还发现了CSS3的变量新特性,有空去深入一下,参考MDN文档,貌似兼容性还不太好。

3. Array Cardio

这里练习Array的相关使用,包括filtermapsortreducesomeeveryfindfindIndexslice,此外还出现了数组的解构赋值,这个平常用的比较少,对象的解构赋值倒是用的比较多。

突然发现reduce居然还可以创建一个哈希表,我之前的操作真是弱爆了

    const transportation = data.reduce(function(obj, item) {
      if (!obj[item]) {
        obj[item] = 0;
      }
      obj[item]++;
      return obj;
    }, {});

顺便吐槽一下自己,每次使用reduce都要去翻文档,真是蛋疼~参考文档,应了那句“半罐水叮当响”,学东西还是要钻研一下才行啊。

其中findIndex貌似也是第一次见到,貌似跟indexOf差不多

findIndex()方法返回数组中满足提供的测试函数的第一个元素的索引

原来含义都不相同,跟find一样,用来筛选数组中的元素。

4. Flex Panels

transitionend事件对象包含的propertyName用来判断是哪一个属性结束动画

字符串的includes用来判断是否包含子字符串,比之前使用indexOf判断结果>-1要更好用,因为返回的就是布尔值,参考文档

5. Type Ahead

突然发现了fetch这个API,表示居然一直没有见过!!!

var url = "http://localhost:9999/1.php"
fetch(url).then(res=>res.json()).then(res=>{
    console.log(res)
})

天地良心,这个api比ajax好用得多!想起上次面试笔试手写两页的ajax封装都是泪~关于fetch我觉得可以另外再起几篇博客,参考文档

6. Fun with HTML5 Canvas

一直以来对于Canvas都存在敬畏之心,感觉要写出酷炫的东西太难了~

这里还了解到了hsl颜色,虽然之前见过却没有深入,参考

  • H表示颜色范围,取值范围是0~360的圆心角
  • S表示色彩的饱和度,数值越大,色彩中的灰度越小,颜色越明亮
  • L表示色彩的明度,控制色彩的明暗变化,数值越大,越接近白色

7. Hold Shift and Check Checkboxes

使用:checked伪类来控制兄弟元素的样式,此外click事件对象还有一个shiftKey的属性,判断是否按下了shift键。

使用原生的JavaScript来操作DOM看起来也十分简洁,比如判断复选框是否选中

// js
this.checked
// jquery
$(this).prop("checked")
$(this).is(":checked")

如果全世界都用Chrome该多好。

8. Slide in on Scroll

实现了一个可以立即执行debounce函数

function debounce(func, wait = 20, immediate = true) {
    var timeout;
    return function () {
        var context = this, args = arguments;
        var later = function () {
            timeout = null;
            if (!immediate) func.apply(context, args);
        };
        var callNow = immediate && !timeout;
        clearTimeout(timeout);
        timeout = setTimeout(later, wait);
        if (callNow) func.apply(context, args);
    };
};

貌似有点bug,事件一直触发,callNow一直为false导致函数无法被调用

btn.addEventListener("click", debounce(function(){
    console.log(1);
}, 500))

9. JS Reference VS Copy

之前对于const的理解漏掉了一个很重要的地方。参考文档 在JavaScript中,常量的值只是不能通过再赋值改变,而对于其值本身却可以修改,比如增减数组元素、修改对象属性

const a = [1,2,3];
a[3] = 1000; // [1,2,3,1000]

a = [1,2]; // TypeError: Assignment to constant variable

const obj = { x: 1 };
obj.y = 100; 
obj = { y:100 }; // 同上

10. Webcam Fun

Canvas中可以通过contenx.getImageData来操作每个像素点,这个函数返回的对象包含一个Uint8ClampedArrayTypedArray,这个是一个颜色数组,按索引值顺序4个值为一组,分别表示

  • R 红色 (0-255)
  • G 绿色 (0-255)
  • B 蓝色 (0-255)
  • A alpha 通道 (0-255; 0 是透明的,255 是完全可见的)

这在之前Canvas粒子动画中了解到,但是并没有深入

11. SpeechRecognition

MD到今天才知道浏览的语音识别和语音合成功能,这简直是太高大上了,附上张鑫旭-HTML5语音合成Speech Synthesis API简介

12. Event Capture, Propagation, Bubbling and Once

addEventListener函数的第三个参数原来不仅仅只是用来区分事件捕获和冒泡的。 实际上有好几种重载形式,可以通过传入配置参数取代常见的事件传递

a.addEventListener("click", function(){}, {
    capture: false, // 跟直接传入false等效
    once: true
})

13. 总结

大概看完了所有demo,原生的Javascript也可以写出很清晰的代码,接下来需要学习的东西包括:

  • fetch
  • canvas
《同构JavaScript应用开发》读书笔记 mockjs使用心得