精华内容
下载资源
问答
  • javascript笔记 JavaScript高级程序设计第四版读书笔记
  • 本文视频版【红宝书】Javascript高级程序设计第四版详细测评_哔哩哔哩 (゜-゜)つロ 干杯~-bilibili​www.bilibili.com简介哈喽大家好, 我是大圣,上次做了一个js的书籍测评,评价还不错,在做css和node之前,再做几...

    59fcf22cf5c3ff9f620f1052d32faf71.png

    本文视频版

    【红宝书】Javascript高级程序设计第四版详细测评_哔哩哔哩 (゜-゜)つロ 干杯~-bilibiliwww.bilibili.com
    45d7347f45a9d367dfd71487f41c893a.png

    简介

    哈喽大家好, 我是大圣,上次做了一个js的书籍测评,评价还不错,在做css和node之前,再做几本书的详细推荐吧, 国庆今天又在家好好读了几本具有代表性的

    1. javascript高级程序设计【红宝书】
    2. javascript忍者秘籍
    3. 你不知道的javascript 【小黄书】
    4. javascript语言精粹与编程实践【绿皮书】
    5. how javascript works
    6. javascript20年(电子八卦书)

    77aa7251df6afb21bce3de2e36a77f7d.png

    先来红宝书吧,这本书一直都是体系化学习js必备的书籍,第四版相比于第三版,多了很多,整本书分成三个大模块,全面使用最新的语法, 国庆又详细的看了一遍

    1. Ecmascript语法
      1. 基础内容
      2. 进阶操作
      3. 新增了迭代器,代理反射,期约(Promise)三个章节
    2. bom和dom
      1. 浏览器宿主环境的相关api
    1. javascript api
      1. js相关的进阶api
      2. 新增了模块和工作者线程(web worker)
      3. 最佳实践

    这本书详细的构建了整个javascript开发者所需要的知识体系,所以建议这本书作为体系化学习的开始, 读2~3遍后,再去阅读其他进阶和垂直领域的js书籍,效果倍棒

    104cb6f0282ba9d41a9fd5f82b31eff6.png

    版本

    ff7490e2c5ff587e556d78bc9385bf2a.png

    我手里有的只有234三本 ,第四版换作者了,精彩依旧,体系化依旧是是红宝书的最大特点,借鉴winter的书评,这本书最大的特点就是体系化的前端教程,它是可以用来做教材的,javascript这几年很多好书,都是讲单点的,建议大家用这本书来构建前端开发的知识体系,再去看别的书和框架,构建前端程序员的核心竞争力 推荐给大家

    第四版的另外一个特色,是很多章节都带上了二维码,扫码可以看到官方对这一节的解读,体验不错, 不过如果视频能换成大妹子+露脸就更好了

    Ecmascript

    前三章

    第一章相关的历史更推荐《javascript20年》,第二三章是基础,有js基础的随便翻翻就好,值得注意的是第二章增加了symbol,第三章的位运算,这些都是在vue3源码里出现的,位运算关系到vue3的组合静态标记中的patchFlagreact源码中的EventFlag,一定要搞明白,而且位运算本身就是做组合权限教研的最佳实践,按位或授权,按位与校验权限,除了理解vue3和react源码外,我们做组件开发的时候也用的到

    241495310f65635138f679b2ac969a8b.png

    8e5c4526ef57ca8687d8f4499b0ffa28.png

    变量作用域与内存

    这一章和第三版差不多,主要是讲清楚原始类型和引用类型,一个图就能搞明白,帮我们理解传参至关重要,除了undefined,null,boolean,number ,string,symbol是原始值,传递的时候是影分身, 其他都是引用,还是指向你自己, 修改会有副作用

    let obj1 = new Object();
    let obj2 = obj1;
    obj1.name = "lsp";
    console.log(obj2.name);  // "lsp"
    

    还有就是作用域链的查询,配合乱遭的变量提升、块级作用域、闭包,是众多骚包面试官喜欢的笔试题,与其刷题不如一次性搞清楚,配合小黄书上册,基本就通了

    最后是垃圾回收,机制有点像《寻梦环游记》,一个人的死亡并不是重点,被所有人遗忘后,才会被清理,变量也是如此, 如何利用垃圾回收机制去优化自己的代码,书中也给出了几个中肯的建议

    内置引用类型

    这两张主要是介绍内置各种乱遭的数据类型,比如Date,Regex,math,以及集合的引用类型arr,obj,set,map等,值得注意的是weakmap的讲解,会让大家对vue3的源码理解有所帮助

    看到书里解释weak是弱弱的拿着,所以不会阻止垃圾回收的时候,我笑了,翻译还是挺萌的,并且书里对定型数组的讲解,还是蛮不错的

    6d1223cb88a9446772c64f61cd17e653.png

    迭代器、生成器、面向对象、代理

    自带的for循环比较明显的劣势就是需要知道如何迭代,es6之后的迭代器就是为了解决这个问题,没有代码讲起来比较飘忽

    大概意思就是,定义了可迭代的协议,只要我们实现了这个协议的要求,也就是规定好【Symbol.iterator】这个key的行为,就可以通过迭代器去消费,不一定非得是数组或者对象

    070b5bfa2daad42f2ae5bdc682de8813.png

    生成器也贼牛逼,可以在一个函数内部暂停,也就是一个用*定义的生成器函数,内部遇见yield,就会暂停执行,知道调用next来恢复执行

    关于对象讲解了对象的configurable,enumberable,wirtable,value几个数据属性,分别对应着数据的能否删除,能否通过for in循环访问,能否修改和实际的值,介绍了一堆es6+的增强语法,然后详细讲解了原型链和继承,还加上了es6的class语法,配合小黄书上册,以后相关的问题你就是专家,和面试官谈笑风生

    然后就是学习vue3必备的Proxy和Reflect了, 响应式必备 快去看书吧,看完这章再去研究vue3的reactivity模块巩固一下,效果更佳

    函数和promise

    然后函数章节大家基本都会了,大部分内容大家都耳熟能详了,关于尾递归优化的小节值得关注,然后就是热度最广的期约与异步函数了,包括基本的使用,promise的合成策略呀,一些第三方的扩展等,

    关于promise的翻译,上个测评我讲过了,我问过hax,是future+promise的结合体, 我也觉得没必要翻译,但是如果翻译的话,我觉得期约还是挺准确的,毕竟总有一天这些术语都要翻译,否则技术书籍里的英文单词会越来越远

    配合promise和async await,我们可以写出更简洁和容易理解的代码,也是现代前端必备的技能了,这一章配合小黄书中册,以及绿皮书对promise的剖析,绝对是进阶必备

    以上都是js的语言规范,然后推荐大家关注tc39的github,会有很多新语法的讨论,了解新语法的来龙去脉,stage3的浏览器就基本是先了,stage2就是非常有潜力的天,我比较关注的比如Temporal处理事件class fields

    能在语言的设计阶段就能围观甚至参与,绝对是装逼必备技能,这里推荐关注我的技术偶像之一hax,tc39委员会成员

    031fda2392e1479410de2eb731f78a03.png

    7e2594435bbda4353607c89236d22e82.png

    bom和dom

    bom和客户端检测

    然后就是浏览器环境了,所谓的bom和dom,bom没啥多介绍的,大家耳熟能详了,window,location控制导航,navigator了解浏览器,history操作浏览历史等

    客户端检测章节主要就是判断各个浏览器,这一块我建议大家阅读司徒正美的《javascript框架设计》,关于浏览器检测讲的最深入,不过现在这个现代浏览器横行的时代,这块内容过一下就好

    dom

    这块大部分内容也就是复习了,包括nodeType的12个数字都是啥意思,常见的dom操作,去瞅瞅dom启蒙作为复习资料也不错

    有一个新的MutationObserver接口值得关注,可以观察dom的变化,比如属性,子节点的变化,都可以记录下来,这个用来做用户行为监控,以及做fmp的性能统计,也就是首屏啥时候渲染出来,还可以设置不同元素的权重,比如video权重高等,统计出一个现在关键的性能治疗fmp,都是很好用的api

    然后就是一些扩展,大家也都很熟悉了,比如querySelector啥的,值得一提的是关于dom的遍历,使用NodeIterator和TreeWalker可以非常方便的进行dom深度优先遍历,还有范围选择api,都值得一读,这些新的api可能会对后续的vue和react的虚拟dom实现有一些影响

    然后关于事件就当复习了,里面关于ie兼容性的内容为觉得有些多余,总的来说事件的方方面面都介绍到了,dom2和dom3的规范,界面事件,鼠标事件,滚轮,键盘还有合成事件,触摸事件等乱糟的, 不过还是有些细节没介绍到, 比如once配置可以只触发一次, 这个也是我看vue3源码才知道的

    b0e13e2cda57a14b28ac9e536531b9b5.png

    de33b3d41dc68acbb67edf213c07c5f2.png

    然后就是canvas,webgl的入门,表单脚本和错误处理调试,处理xml,这部分第三版其实都有没啥多说的

    Javascript API

    剩下的部分统称为javascript api,基本都是比第三版多出来的内容,非常推荐阅读了解

    比如20章就是一堆html5的新api入门,编码,文件,媒体元素,拖放,通知,页面显隐,web component

    然后网络请求部分除了xmlhttprequest,跨域之外,多了fetch api,beacon api和websocket

    客户端存储除了cookie还有localstorage和indexdb

    新增的es6模块值得关注,讲解了模块系统的发展史,但是没讲到我喜欢的seajs ,差评

    除了es6本身的模块系统知识外,也介绍了浏览器里面的script,加上type=module后,就直接支持了import语法,这个就是vue3配套的vite工具的原理了,我写过一个vite源码的文章,欢迎移步, 通过拦截import的请求实现工程化,在不远的未来可能会取代webpack的地位,还不快去好好学习

    然后就是web worker,翻译成工作者线程,感觉还不如叫影分身,囧,这一章还是蛮有必要的,大部分js开发者都没有多进程的概念,学完这个我们就知道碰见耗时的任务偷桃子,我们完全可以用猴子猴孙去做,不耽误主进程去和七仙女去讲述葫芦娃从石头里蹦出来的故事,比如我们常见的面试题,大文件上传,计算文件md5这个任务用webworker就是比较合理的场景

    992614dce37ede44f5ab662ab3f77216.png

    最后的最佳实践 没啥说的了,就是常见的优化策略,这部分只是一个入门,后续需要看别的书看进阶,后面框架的推荐竟然还有mooltools等过时的库,所以不看也罢,不如我以后做一起现代的工具推荐

    总结

    总的来说这本书绝对是前端的重要参考书,借鉴winter的书评,这本书最大的特点就是体系化的前端教程,它是可以用来做脚踩的,javascript这几年很多好书,都是讲单点的

    建议大家用这本书来构建前端开发的知识体系,再去看别的书和框架,构建前端程序员的核心竞争力 推荐给大家

    58a3880c2afdabf9ad5a3d7fee39923b.png

    下期预告 忍者书和小黄书 or javascript20年

    参考资料

    1. tc39 https://github.com/tc39
    2. hax知乎 https://www.zhihu.com/people/he-shi-jun/answers
    3. 《前端会客厅》hax专场 https://www.bilibili.com/video/BV1xT4y1L7ui
    4. Javascript书籍全测评 https://juejin.im/post/6877712145757896717
    展开全文
  • JavaScript高级程序设计第四版 目录 文章目录前言注意个人体会推荐1. 什么是JavaScriptDOm2. HTML中的JavaScript` 前言 本文章来源为:《JavaScript高级程序设计》(第四版),如有机会,请以书中内容为主。 注意 ...

    JavaScript高级程序设计第四版 目录


    前言

    本文章来源为:《JavaScript高级程序设计》(第四版),如有机会,请以书中内容为主。

    注意

    • 此文不涉及基础语法,如有需要可观看菜鸟教程

    个人体会

    第四版这本书啃起来有点难啃。迭代器,原型链,promise还是有一定了解才行,否则阅读起来有点生硬。
    node毕竟是单线程非阻塞的语言,为了模拟多线程,会出现async和await这种东西,精髓是在回调函数上。

    推荐

    • 《JavaScript高级程序设计》(第四版)
    • 《JavaScript学习指南》

    1. 什么是JavaScript

    DOm

    文档对象模型(DOM):是一个应用编程接口(API)

    <html>
    <head>
    	<title>xxx</title>
    </head>
    <body>
    <p>xxxx</p>
    </body>
    </html>
    

    图例:
    在这里插入图片描述

    2. HTML中的JavaScript

    <script>元素

    属性

    • async:立刻下载脚本
    • charset:指定的代码字符集
    • crossorigin:跨资源共享设置
    • defer:在文档解析和显示完成后再执行脚本
    • integrity:允许比对接收到的资源和指定的加密签名,已验证子资源的完整性。用于CDN
    • language
    • src
    • type:代码块中脚本语言的内容类型。如果是module,则被当作ES6模块

    动态加载脚本

    let script = document.createElement('script');
    script.src = 'test.js'
    document.head.appendChild(script);
    

    XHTML中的变化

    XHTML是将HTML作为XML重新包装的结果。

    区别

    • XHTML使用JavaScript必须指定type=text/javascript
    • 规则严格
    • 已经废弃
    • //<!CDATA //]]>

    3. 语言基础

    内容概括

    • 语法
    • 数据类型
    • 控制语句
    • 函数

    此文不涉及基础语法,可观看菜鸟教程

    严格模式

    • 处理不规范写法
    • use strict

    Symbol类型

    ECMAScript6新增数据类型

    • 符号是原始值
    • 符号实例时唯一、不可变的
    • 用于确保对象属性使用唯一标识符,不会出现冲突

    符号的基本用法

    Symbol()函数初始化

    let sym = Symbol();
    console.log(typeof sym);	// symbol
    

    传入字符串对符号描述

    let genericSymbol = Symbol();
    let otherGenericSymbol = Symbol();
    
    let foolSymbol = Symbol('foo');
    let otherFoolSymbol = Symbol('foo');
    
    console.log(genericSymbol == otherGenericSymbol);
    console.log(foolSymbol == otherFoolSymbol);
    

    Symbol函数不能用作构造函数

    • 不能和new一起使用

    全局符号注册表 - symbol.for

    如果运行时的不同部分需要共享和重用符号实例:

    • 用一个字符串作为键
    • 全局符号注册表中创建并重用符号
    • Symbol.for()方法
    // 创建新符号
    let fooGlobalSymbol = Symbol.for('foo');
    // 重用已有符号
    let otherFooGlobalSymbol = Symbol.for('foo');
    
    console.log(fooGlobalSymbol === otherFooGlobalSymbol);  // true
    

    symbol.for

    • 对每个字符串键都执行幂等操作
    • 第一次使用某个字符串调用时,会检查全局运行时注册表
    • 如果不存在对应的符号,会生成一个新符号实例并添加到注册表中
    • 后续使用相同的字符串调用时,会先检查注册表,发现对应的符号返回该符号实例
    • 全局注册表中的符号必须为字符串,任何值都会被转换为字符串
    • 类似于设计模式中的单例模式

    • symbol与symbol.for定义的结果是不同的
    let test1 = Symbol('foo');
    let test2 = Symbol.for('foo');
    
    console.log(test1 === test2);   // false
    

    查询全局注册表 - symbol.keyFor

    • 接收符号,返回该全局符号对应的字符串键
    • 如果查询的不是全局符号,则会返回undefined
    // create global symbol
    let s = Symbol.for('foo');
    console.log(Symbol.keyFor(s));  // foo
    
    // create ordinary symbol
    let s2 = Symbol('bar');
    console.log(Symbol.keyFor(s2)); // undefined
    
    // type error
    console.log(Symbol.keyFor(123));
    

    使用符号作为属性

    可以用字符串或者数值作为属性的地方,都可以使用符号。
    包括:

    • 对象字面量属性,只能在计算属性语法中使用符号作为属性
    • Object.defineProperty()
    • Object.definedProperties()
    let s1 = Symbol('foo'),
        s2 = Symbol('bar'),
        s3 = Symbol('baz'),
        s4 = Symbol('qux');
    
    let o = {
        [s1]: 'foo val'
    };
    
    console.log(o);
    
    o[s2] = 'foo val2';
    console.log(o);
    

    在这里插入图片描述

    获取对象实例的四种用法

    • Object.getOwnPropertyNames():返回对象实例的常规属性数组
    • Object.getOwnPropertySymbols():返回对象实例的符号属性数组
    • Object.getOwnPropertyDescriptors():返回同时包含常规和符号属性描述符的对象
    • Reflect.ownKeys():返回两种类型的键
    console.log(Object.getOwnPropertyNames(o));
    console.log(Object.getOwnPropertySymbols(o));
    console.log(Object.getOwnPropertyDescriptor(o));
    console.log(Reflect.ownKeys(o));
    
    注意
    • 符号属性是对内存中符号的一个引用
    • 直接创建并用作属性的符号不会丢失
    • 如果没有显式地保存这些属性的引用,必须遍历对象的所有符号属性才能找到响应的属性键
    let o = {
        [Symbol('foo')]: 'foo val',
        [Symbol('bar')]: 'bar val'
    };
    
    console.log(o);
    
    let barSymbol = Object.getOwnPropertySymbols(o)
                    .find((symbol) => 
                        symbol.toString().match(/bar/)
                    );
    
    console.log(barSymbol);
    

    常用内置符号

    • 用于暴露语言内部行为,可以直接访问、重写或模拟这些行为
    • 都以Symbol工厂函数字符串属性的形式存在
    • 常用于重新定义,改变原生结构的行为

    注意

    • 引用符号在规范中的名称,前缀为@@,如@@iterator指的就是Symbol.iterator

    Symbol.asyncIterator

    • 该方法返回对象默认的AsyncIterator,由for-await-of使用
    • 这个符号表示实现异步迭代器API的函数
    • for-await-of循环时,执行异步迭代操作,调用以Symbol.asyncIterator为键的函数,返回一个实现迭代器的API对象
    • 对象是实现API的AsyncGenerator
    class Foo {
        async *[Symbol.asyncIterator]() {}
    }
    
    let f = new Foo();
    
    console.log(f[Symbol.asyncIterator]());	// Object [AsyncGenerator] {}
    
    • 这个由Symbol.asyncIterator生成的对象应该通过其next()方法陆续返回Promise实例
    • 既可以通过显示调用next()方法返回,也可以通过隐式调用异步生成器函数返回
    class Emitter {
        constructor(max) {
            this.max = max;
            this.asyncIdx = 0;
        }
        // 异步迭代器的API
        async *[Symbol.asyncIterator] () {
            while(this.asyncIdx < this.max) {
                yield new Promise((resolve) => resolve(this.asyncIdx++));
            }
        }
    }
    
    async function asyncCount() {
        let emitter = new Emitter(5);
    
        // 循环时,异步迭代操作
        for await(const x of emitter){
            console.log(x);
        }
    }
    
    asyncCount();
    

    注意

    • symbol.asyncIterator只支持ES2018规范

    Symbol.hasInstance

    • 该方法决定一个构造器对象是否认可一个对象时它的实例,由instanceof操作符使用
    • instanceof操作符可以确定一个对象实例的原型链上是否有原型
    function Foo() {}
    let f = new Foo();
    console.log(f instanceof Foo);  // true
    
    class Bar{}
    let b = new Bar();
    console.log(b instanceof Bar);  // true
    
    • instanceof会使用Symbol.hasInstance确定关系

    Symbol.hasInstance为键

    function Foo() {}
    let f = new Foo();
    console.log(Foo[Symbol.hasInstance](f));  // true
    
    class Bar{}
    let b = new Bar();
    console.log(Bar[Symbol.hasInstance](b));  // true
    

    重新定义函数

    • 这个属性定义在function原型上,默认所有函数和类上都可以调用
    • 可以在继承的类上通过静态方法重新定义这个函数
    class Bar{};
    class Baz extends Bar {
        static [Symbol.hasInstance]() {
            return false;
        }
    }
    
    let b = new Baz();
    console.log(Bar[Symbol.hasInstance](b));  // true
    console.log(b instanceof Bar);  //true
    console.log(Baz[Symbol.hasInstance](b));  //false
    console.log(b instanceof Baz);  //false
    
    

    Symbol.isConcatSpreadable

    • 布尔值,如果是true,意味着对象应该用Array.prototype.concat()打平其数组元素
    • Array.prototype.concat()会根据接收到的对象类型选择如何将一个类数组对象拼接成数组实例
    • false: 默认追加到数组末尾
    • true: 被打平到数组实例
    • 其他不是类数组对象的对象,在Symbol.isConcatSpreadable被设置为true的情况下忽略
    let initial = ['foo'];
    
    let array = ['bar'];
    // false
    console.log(array[Symbol.isConcatSpreadable]);  // undefined
    console.log(initial.concat(array));  // ['foo', 'bar']
    array[Symbol.isConcatSpreadable] = false;
    console.log(initial.concat(array));  //['foo', Array(1)]
    // true
    let arrayLikeObject = { length: 1, 0: 'baz'};
    console.log(arrayLikeObject[Symbol.isConcatSpreadable]);  //undefined
    console.log(initial.concat(arrayLikeObject));  //['foo', {...}]
    arrayLikeObject[Symbol.isConcatSpreadable] = true;
    console.log(initial.concat(arrayLikeObject));  //['foo', 'baz']
    // set
    let otherObject = new Set() . add('qux');
    console.log(otherObject[Symbol.isConcatSpreadable]);  //undefined
    console.log(initial.concat(otherObject));  // ['foo', Set(1)]
    otherObject[Symbol.isConcatSpreadable] = true;
    console.log(initial.concat(otherObject));  // ['foo']
    

    在这里插入图片描述

    Symbol.iterator

    • 该方法返回对象默认的迭代器,由for-of使用
    class Foo {
        *[Symbol.iterator]() {}
    }
    
    let f = new Foo();
    
    console.log(f[Symbol.iterator]);
    

    在这里插入图片描述

    • 显示next()
    • 隐式生成器函数
    class Emitter{
        constructor(max) {
            this.max = max;
            this.idx = 0;
        }
    
        *[Symbol.iterator]() {
            while(this.idx < this.max){
                yield this.idx++;
            }
        }
    }
    
    function count() {
        let emitter = new Emitter(5);
    
        for (const x of emitter){
            console.log(x);
        }
    }
    
    count();
    

    symbol.match

    • 正则表达式法,用正则表达式去匹配字符串
    • String.prototype.match()
    • String.prototype.match()会使用Symbol.match为键的函数来对正则表达式求值
    • 正则表达式的原型上默认有这个函数的定义,因此所有正则表达式实例默认是这个String方法的有效参数
    console.log(RegExp.prototype[Symbol.match]);
    
    console.log('foobar'.match(/bar/));
    

    在这里插入图片描述

    • 如果传入非正则表达式值,会导致该值被转换为regexp对象
    • 重新定义symbol.match,可直接使用实例
    class FooMatcher {
        static [Symbol.match](target){
            return target.includes('foo');
        }
    }
    
    console.log('foobar'.match(FooMatcher));    // true
    console.log('barbaz'.match(FooMatcher));    //false
    
    class StringMatcher{
        constructor(str){
            this.str = str;
        }
    
        [Symbol.match](target){
            return target.includes[this.str];
        }
    }
    
    console.log('foobar'.match(new StringMatcher('foo')));  // true
    console.log('barbaz'.match(new StringMatcher('qux')));  //false
    

    symbol.replace

    • 替换一个字符串中匹配的子串,由String.prototype.replace()使用
    console.log(RegExp.prototype[Symbol.replace]);
    
    console.log('foobarbaz'.replace(/bar/, 'qux'));
    

    在这里插入图片描述

    class FooReplacer {
        static [Symbol.replace] (target, replacement) {
            return target.split('foo').join(replacement);
        }    
    }
    
    console.log('barfoobaz'.replace(FooReplacer, 'qux'));
    
    class StringReplacer {
        constructor(str){
            this.str = str;
        }
        
        [Symbol.replace](target, replacement){
            return target.split(this.str).join(replacement);
        }
    }
    
    console.log('barfoobaz'.replace(new StringReplacer('foo'), 'qux'));
    

    在这里插入图片描述

    Symbol.search

    • 返回字符串中匹配正则表达式的索引
    class FooSearch {
        static [Symbol.search](target) {
            return target.indexOf('foo');
        }
    }
    
    console.log('foobar'.search(FooSearch));    // 0
    console.log('barfoo'.search(FooSearch));    // 3
    console.log('barbaz'.search(FooSearch));    // -1
    
    class StringSearch {
        constructor(str) {
            this.str = str;
        }
    
        [Symbol.search](target){
            return target.indexOf(this.str);
        }
    }
    
    console.log('foobar'.search(new StringSearch('foo')));  // 0
    console.log('barfoo'.search(new StringSearch('foo')));  // 3
    console.log('barbaz'.search(new StringSearch('foo')));  // -1
    

    在这里插入图片描述

    symbol.species

    • 创建派生对象的构造函数
    • symbol.species定义静态的获取器(getter),覆盖新创建实例的原型定义
    class Bar extends Array {}
    class Baz extends Array {
        static get [Symbol.species]() {
            return Array;
        }
    }
    
    let bar = new Bar();
    console.log(bar instanceof Array);  // true
    console.log(bar instanceof Bar);    // true
    
    bar = bar.concat('bar');
    console.log(bar instanceof Array);  // true
    console.log(bar instanceof Bar);    // true
    
    let baz = new Baz();
    console.log(baz instanceof Array);  // true
    console.log(baz instanceof Baz);    // true
    
    baz = baz.concat('baz');
    console.log(baz instanceof Array);  // true
    console.log(baz instanceof Baz);    // false
    

    symbol.split

    • 该函数作为创建派生对象的构造函数
    class FooSplitter {
        static [Symbol.split](target){
            return target.split('foo');
        }
    }
    
    console.log('barfoobaz'.split(FooSplitter));
    
    class StringSplitter {
        constructor(str){
            this.str = str;
        }
    
        [Symbol.split](target){
            return target.split(this.str);
        }
    }
    
    console.log('barfoobaz'.split(new StringSplitter('foo')));
    

    在这里插入图片描述

    symbol.toPrimitive

    • 将对象转换为相应的原始值
    class Foo {}
    let foo = new Foo();
    
    console.log(3 + foo);   
    console.log(3 - foo);
    console.log(String(foo));
    
    class Bar {
        constructor() {
            this[Symbol.toPrimitive] = function(hint) {
                switch(hint) {
                    case 'number':
                        return 3;
                    case 'string':
                        return 'string bar';
                    case 'default':
                    default:
                        return 'default bar';
                }
            }
        }
    }
    
    let bar = new Bar();
    
    console.log(3 + bar);
    console.log(3 - bar);
    console.log(String(bar));
    

    在这里插入图片描述

    symbol.toStringTag

    • 该字符串用于创建对象的默认字符串描述
    • Object.prototype.toString()
    let s = new Set();
    
    console.log(s);     // Set[0] {}
    console.log(s.toString());      // [Object Set]
    console.log(s[Symbol.toStringTag]); //Tag
    
    class Foo {}
    let foo = new Foo();
    
    console.log(foo);       // Foo {}
    console.log(foo.toString());    // [object Object]
    console.log(foo[Symbol.toStringTag]);   // undefined
    
    class Bar {
        constructor(){
            this[Symbol.toStringTag] = 'Bar';
        }
    }
    let bar = new Bar();
    
    console.log(bar);       // Bar {}
    console.log(bar.toString());    // [object object]
    console.log(bar[Symbol.toStringTag]);   // bar
    

    在这里插入图片描述

    Object

    • 对象其实就是一组数据和功能的集合
    • let o = new Object()
    • Object也是派生其他类的基类,Object类所有属性和方法在派生的对象上同样存在

    每个Object类的属性和方法

    1. constructor
    2. hasOwnProperty(propertyName):判断当前对象实例是否存在给定属性
    3. isPrototypeof(object):判断当前对象是否为另一个对象的原型
    4. propertyIsEnumerable(propertyName):判定给定的属性是否可以使用
    5. toLocaleString():返回对象的字符串表示
    6. toString()
    7. valueOf()

    for-in 语句

    • 严格的迭代语句,用于枚举对象中的非符号键属性
    • for (property in expression) statement

    for-of 语句

    • 迭代语句,遍历可迭代对象的元素
    • for (property of expression) statement

    with语句

    • 将代码作用域设置为特定的对象
    • with (expression) statement
    • 主要是针对一个对象反复操作
    let qs = location.search.substring(1);
    let hostname = location.hostname;
    let url = location.href;
    
    with(location) {
        let qs = search.substring(1);
        let hostname = hostname;
        let url = href;
    }
    
    • 严格模式不允许使用with

    严格模式的限制

    1. 函数不能以eval或者arguments作为名称
    2. 函数的参数不能叫做eval或者arguments
    3. 两个函数的参数不能教同一个名称

    **如果违反以上规则,将会导致语法错误,代码也不会运行**

    展开全文
  • 好的学习资料必须分享-JavaScript高级程序设计 第四版 全面、深入地介绍了JavaScript开发者必须掌握的前端开发技术,涉及JavaScript的基础特性和高级特性。书中详尽讨论了JavaScript的各个方面,从JavaScript的起源...

    好的学习资料必须分享-JavaScript高级程序设计 第四版

    全面、深入地介绍了JavaScript开发者必须掌握的前端开发技术,涉及JavaScript的基础特性和高级特性。书中详尽讨论了JavaScript的各个方面,从JavaScript的起源开始,逐步讲解到新出现的技术,其中重点介绍ECMAScript和DOM标准。在此基础上,接下来的各章揭示了JavaScript的基本概念,包括类、期约、迭代器、代理,等等。另外,书中深入探讨了客户端检测、事件、动画、表单、错误处理及JSON。本书同时也介绍了近几年来涌现的重要新规范,包括Fetch API、模块、工作者线程、服务线程以及大量新API。

    本文来源于:http://www.91apps.cn/

    下载地址:JavaScript高级程序设计 第四版

    展开全文
  • 简介哈喽大家好, 我是大圣,上次做了一个js的书籍测评,评价还不错,在做css和node之前,再做几本书的详细推荐吧, 国庆今天又在家好好读了几本具有代表性的javascript高级程...

    简介

    哈喽大家好, 我是大圣,上次做了一个js的书籍测评,评价还不错,在做css和node之前,再做几本书的详细推荐吧,  国庆今天又在家好好读了几本具有代表性的

    1. javascript高级程序设计【红宝书】

    2. javascript忍者秘籍

    3. 你不知道的javascript 【小黄书】

    4. javascript语言精粹与编程实践【绿皮书】

    5. how javascript works

    6. javascript20年(电子八卦书)

    img

    先来红宝书吧,这本书一直都是体系化学习js必备的书籍,第四版相比于第三版,多了很多,整本书分成三个大模块,全面使用最新的语法, 国庆又详细的看了一遍

    1. Ecmascript语法

      1. 基础内容

      2. 进阶操作

      3. 新增了迭代器,代理反射,期约(Promise)三个章节

    2. bom和dom

      1. 浏览器宿主环境的相关api

    3. javascript api

      1. js相关的进阶api

      2. 新增了模块和工作者线程(web worker)

      3. 最佳实践

    这本书详细的构建了整个javascript开发者所需要的知识体系,所以建议这本书作为体系化学习的开始, 读2~3遍后,再去阅读其他进阶和垂直领域的js书籍,效果倍棒

    image-20201008061120962

    版本

    image-20201006214121858

    我手里有的只有234三本  ,第四版换作者了,精彩依旧,体系化依旧是是红宝书的最大特点,借鉴winter的书评,这本书最大的特点就是体系化的前端教程,它是可以用来做教材的,javascript这几年很多好书,都是讲单点的,建议大家用这本书来构建前端开发的知识体系,再去看别的书和框架,构建前端程序员的核心竞争力 推荐给大家

    第四版的另外一个特色,是很多章节都带上了二维码,扫码可以看到官方对这一节的解读,体验不错, 不过如果视频能换成大妹子+露脸就更好了

    Ecmascript

    前三章

    第一章相关的历史更推荐《javascript20年》,第二三章是基础,有js基础的随便翻翻就好,值得注意的是第二章增加了symbol,第三章的位运算,这些都是在vue3源码里出现的,位运算关系到vue3的组合静态标记中的patchFlag和react源码中的EventFlag,一定要搞明白,而且位运算本身就是做组合权限教研的最佳实践,按位或授权,按位与校验权限,除了理解vue3和react源码外,我们做组件开发的时候也用的到

    image-20201005070058425
    image-20201005064951859

    变量作用域与内存

    这一章和第三版差不多,主要是讲清楚原始类型和引用类型,一个图就能搞明白,帮我们理解传参至关重要,除了undefined,null,boolean,number ,string,symbol是原始值,传递的时候是影分身, 其他都是引用,还是指向你自己, 修改会有副作用

    let obj1 = new Object();
    let obj2 = obj1;
    obj1.name = "lsp";
    console.log(obj2.name);  // "lsp"
    

    还有就是作用域链的查询,配合乱遭的变量提升、块级作用域、闭包,是众多骚包面试官喜欢的笔试题,与其刷题不如一次性搞清楚,配合小黄书上册,基本就通了

    最后是垃圾回收,机制有点像《寻梦环游记》,一个人的死亡并不是重点,被所有人遗忘后,才会被清理,变量也是如此, 如何利用垃圾回收机制去优化自己的代码,书中也给出了几个中肯的建议

    内置引用类型

    这两张主要是介绍内置各种乱遭的数据类型,比如Date,Regex,math,以及集合的引用类型arr,obj,set,map等,值得注意的是weakmap的讲解,会让大家对vue3的源码理解有所帮助

    看到书里解释weak是弱弱的拿着,所以不会阻止垃圾回收的时候,我笑了,翻译还是挺萌的,并且书里对定型数组的讲解,还是蛮不错的

    image-20201005212616083

    迭代器、生成器、面向对象、代理

    自带的for循环比较明显的劣势就是需要知道如何迭代,es6之后的迭代器就是为了解决这个问题,没有代码讲起来比较飘忽

    大概意思就是,定义了可迭代的协议,只要我们实现了这个协议的要求,也就是规定好【Symbol.iterator】这个key的行为,就可以通过迭代器去消费,不一定非得是数组或者对象

    image-20201005214820288

    生成器也贼牛逼,可以在一个函数内部暂停,也就是一个用*定义的生成器函数,内部遇见yield,就会暂停执行,知道调用next来恢复执行

    关于对象讲解了对象的configurable,enumberable,wirtable,value几个数据属性,分别对应着数据的能否删除,能否通过for in循环访问,能否修改和实际的值,介绍了一堆es6+的增强语法,然后详细讲解了原型链和继承,还加上了es6的class语法,配合小黄书上册,以后相关的问题你就是专家,和面试官谈笑风生

    然后就是学习vue3必备的Proxy和Reflect了, 响应式必备 快去看书吧,看完这章再去研究vue3的reactivity模块巩固一下,效果更佳

    函数和promise

    然后函数章节大家基本都会了,大部分内容大家都耳熟能详了,关于尾递归优化的小节值得关注,然后就是热度最广的期约与异步函数了,包括基本的使用,promise的合成策略呀,一些第三方的扩展等,

    关于promise的翻译,上个测评我讲过了,我问过hax,是future+promise的结合体, 我也觉得没必要翻译,但是如果翻译的话,我觉得期约还是挺准确的,毕竟总有一天这些术语都要翻译,否则技术书籍里的英文单词会越来越远

    配合promise和async await,我们可以写出更简洁和容易理解的代码,也是现代前端必备的技能了,这一章配合小黄书中册,以及绿皮书对promise的剖析,绝对是进阶必备

    以上都是js的语言规范,然后推荐大家关注tc39的github,会有很多新语法的讨论,了解新语法的来龙去脉,stage3的浏览器就基本是先了,stage2就是非常有潜力的天,我比较关注的比如Temporal处理事件,class fields

    能在语言的设计阶段就能围观甚至参与,绝对是装逼必备技能,这里推荐关注我的技术偶像之一hax,tc39委员会成员

    image-20201006215835219
    image-20201006215913089

    bom和dom

    bom和客户端检测

    然后就是浏览器环境了,所谓的bom和dom,bom没啥多介绍的,大家耳熟能详了,window,location控制导航,navigator了解浏览器,history操作浏览历史等

    客户端检测章节主要就是判断各个浏览器,这一块我建议大家阅读司徒正美的《javascript框架设计》,关于浏览器检测讲的最深入,不过现在这个现代浏览器横行的时代,这块内容过一下就好

    dom

    这块大部分内容也就是复习了,包括nodeType的12个数字都是啥意思,常见的dom操作,去瞅瞅dom启蒙作为复习资料也不错

    有一个新的MutationObserver接口值得关注,可以观察dom的变化,比如属性,子节点的变化,都可以记录下来,这个用来做用户行为监控,以及做fmp的性能统计,也就是首屏啥时候渲染出来,还可以设置不同元素的权重,比如video权重高等,统计出一个现在关键的性能治疗fmp,都是很好用的api

    然后就是一些扩展,大家也都很熟悉了,比如querySelector啥的,值得一提的是关于dom的遍历,使用NodeIterator和TreeWalker可以非常方便的进行dom深度优先遍历,还有范围选择api,都值得一读,这些新的api可能会对后续的vue和react的虚拟dom实现有一些影响

    然后关于事件就当复习了,里面关于ie兼容性的内容为觉得有些多余,总的来说事件的方方面面都介绍到了,dom2和dom3的规范,界面事件,鼠标事件,滚轮,键盘还有合成事件,触摸事件等乱糟的, 不过还是有些细节没介绍到, 比如once配置可以只触发一次, 这个也是我看vue3源码才知道的

    image-20201006080650548
    image-20201006080056529

    然后就是canvas,webgl的入门,表单脚本和错误处理调试,处理xml,这部分第三版其实都有没啥多说的

    Javascript API

    剩下的部分统称为javascript api,基本都是比第三版多出来的内容,非常推荐阅读了解

    比如20章就是一堆html5的新api入门,编码,文件,媒体元素,拖放,通知,页面显隐,web component

    然后网络请求部分除了xmlhttprequest,跨域之外,多了fetch api,beacon api和websocket

    客户端存储除了cookie还有localstorage和indexdb

    新增的es6模块值得关注,讲解了模块系统的发展史,但是没讲到我喜欢的seajs ,差评

    除了es6本身的模块系统知识外,也介绍了浏览器里面的script,加上type=module后,就直接支持了import语法,这个就是vue3配套的vite工具的原理了,我写过一个vite源码的文章,欢迎移步, 通过拦截import的请求实现工程化,在不远的未来可能会取代webpack的地位,还不快去好好学习

    然后就是web worker,翻译成工作者线程,感觉还不如叫影分身,囧,这一章还是蛮有必要的,大部分js开发者都没有多进程的概念,学完这个我们就知道碰见耗时的任务偷桃子,我们完全可以用猴子猴孙去做,不耽误主进程去和七仙女去讲述葫芦娃从石头里蹦出来的故事,比如我们常见的面试题,大文件上传,计算文件md5这个任务用webworker就是比较合理的场景

    image-20201006222338112

    最后的最佳实践 没啥说的了,就是常见的优化策略,这部分只是一个入门,后续需要看别的书看进阶,后面框架的推荐竟然还有mooltools等过时的库,所以不看也罢,不如我以后做一起现代的工具推荐

    总结

    总的来说这本书绝对是前端的重要参考书,借鉴winter的书评,这本书最大的特点就是体系化的前端教程,它是可以用来做脚踩的,javascript这几年很多好书,都是讲单点的

    建议大家用这本书来构建前端开发的知识体系,再去看别的书和框架,构建前端程序员的核心竞争力 推荐给大家

    image-20201006144255843

    下期预告  忍者书和小黄书 or javascript20年

    参考资料

    1. tc39  https://github.com/tc39

    2. hax知乎 https://www.zhihu.com/people/he-shi-jun/answers

    3. 《前端会客厅》hax专场  https://www.bilibili.com/video/BV1xT4y1L7ui

    4. Javascript书籍全测评  https://juejin.im/post/6877712145757896717

    ❤️看完三件事

    如果你觉得这篇内容对你挺有启发,我想邀请你帮我三个小忙:

    1. 点赞,让更多的人也能看到介绍内容(收藏不点赞,都是耍流氓-_-)

    2. 关注公众号“前端劝退师”,不定期分享原创知识。

    3. 也看看其他文章

    劝退师个人微信:huab119

    也可以来我的GitHub博客里拿所有文章的源文件:

    前端劝退指南:https://github.com/roger-hiro/BlogFN一起玩耍呀

    展开全文
  • 通过索引区分哪些 records 是 update,哪些 records 是 insert(key 一次写入) 对于 update 消息,会直接找到对应 key 所在的最新 FileSlice 的 base 文件,并做 merge 后写新的 base file (新的 FileSlice) 对于...
  • 2020年9月第四版 一 前言 JavaScript与宿主关系密切, 宿主为JavaScript定义了与外界交互所需的全部API: DOM/网络请求/系统硬件/存储/事件/文件/加密/其他API等. 各种浏览器以及JavaScript引擎都按照自己的理解实现...
  • 父节点和它的一个及最后一个子节点也有专门属性:firstChild 和 lastChild 分别指向 childNodes 中的一个和最后一个子节点。 使用 previousSibling 和 nextSibling 可以在这个列 表的节点间导航。 ...
  • 二章 HTML中的JavaScript 2.1 <script>元素 <script>元素的八个属性 使用方式: 【行内JavaScript代码】直接在网页中嵌入JavaScript代码,包含在<script>中的代码会从上到下解析. 在<...
  • 五章 基本引用类型 引用值(或者对象) 是某个特定引用类型的实例。 在ECMAScript中,引用类型是把数据和功能组织到一起的结构,经常被人错误地称作“类”。 虽然从技术上讲 JavaScript 是一门面向对象语言,但...
  • JavaScript 变量是松散类型的,而且变量不过就是特定时间点一个特定值的名称而已。由于没有规则定义变量必须包含什么数据类型,变量的值和数据类型在脚本生命期内可以改变。 4.1 原始值与引用值 ECMAScript 变量包含...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 1,141
精华内容 456
关键字:

javascript高级程序设计第四版

java 订阅