什么是chrome extensions
Chrome Extensions,中文名叫 “Chrome浏览器扩展程序”。引用官方文档的描述,翻译一下就是 “可以修改和增强浏览器功能的 H5 小程序”。 它的入口在浏览器窗口的右上角,地址栏的最右边
Chrome Extensions,中文名叫 “Chrome浏览器扩展程序”。引用官方文档的描述,翻译一下就是 “可以修改和增强浏览器功能的 H5 小程序”。 它的入口在浏览器窗口的右上角,地址栏的最右边
webpack4 最主要的卖点便是零配置,要想成为一位webpack配置工程师怎么能不开始了解呢?话不多说,让我们开始体验 webpack 4 的一些特性。
创建空目录,初始化配置
1 | mkdir webpack4-quickstart |
安装相关依赖
1 | npm i webpack --save-dev |
1 | "scripts":{ |
现代的前端框架react/vue/angular都有路由router的概念,通过手写实现可以帮助我们更好地了解它的工作原理。它们都推荐单页面应用 SPA 开发模式,在路由切换时替换 DOM Tree 中最小修改的部分 DOM,来减少原先因为多页应用的页面跳转带来的巨量性能损耗。它们都有自己的典型路由解决方案,@angular/router、react-router、vue-router等。
一般来说,这些路由插件总是提供两种不同方式的路由方式: Hash 和 History,有时也会提供非浏览器环境下的路由方式 Abstract(支持所有 JavaScript 运行 环境,如 Node.js 服务器端。如果发现没有浏览器的 API,路由会自动强制进入这个模式)。
hash: 地址栏会多出一个#号,对url造成影响,在某些场景下如微信支付有坑。 history: 兼容性差,直接访问报404,需要服务器做处理。
注意: Hash 方法是利用了相当于页面锚点的功能,所以与原来的通过锚点定位来进行页面滚动定位的方式冲突,导致定位到错误的路由路径,因此需要采用别的办法。
Hash 模式是使用 URL 的 Hash 来模拟一个完整的 URL,因此当 URL 改变的时候页面并不会重载。History 模式则会直接改变 URL,所以在路由跳转的时候会丢失一些地址信息(只是动态的通过js操作window.history来改变浏览器地址栏里的路径,并没有发起http请求),在刷新或直接访问路由地址的时候会匹配不到静态资源。因此需要在服务器上配置一些信息,让服务器增加一个覆盖所有情况的候选资源。
history 模式下,前端的 URL 必须和实际向后端发起请求的 URL 一致,如 www.xxx.com/items/id。后端如果缺少对 /items/id 的路由处理,将返回 404 错误。
函数柯里化(function currying)又称部分求值。一个currying的函数首先会接受一些参数,接受了这些参数后,
该函数并不会立即求值,而是继续返回另外一个函数,刚才传入的参数在函数形成的闭包里被保存起来。待到函数真正需要求值的时候,之前传入的参数都会被一次性用于求值。
把接受多个参数的函数变换成接受一个单一参数(最初函数的第一个参数)的函数,并且返回接受余下的参数而且返回结果的新函数。
顾名思义,柯里化其实本身是固定一个可以预期的参数,并返回一个特定的函数,处理批特定的需求。这增加了函数的适用性,但同时也降低了函数的适用范围。
1 | function add(x,y){ |
主流的双向绑定方法 1.发布-订阅模式 通过使用 get 和 set 的方式获取数据然后更新数据,其原理就是监听页面中某个具体元素的事件,然后将其最新的值手动 set 到 数据中,同时订阅 model 层的改变,然后触发页面的渲染更新
2.脏检测 通过对比数据是否有变更,来决定是否更新视图。最简单的可以通过定时轮询去检测数据的变动。Angular 只有在指定事件触发时进入脏检测:
脏检查的主要原理是在将数据绑定到 View 的时候,就在监听器列表(scope 作用域中的监听队列 watchList)中插入一条监听器,当触发 UI 事件或者 Ajax 请求时,就会触发脏检查($digest cycle), 在 $digest 流程中,将遍历每个数据变量的 watcher,比较它的新旧值。当新旧值不同时,触发 listener 函数,执行相关的更新逻辑。这个过程将会一直重复,直到所有数据指令的新旧值都相同为止。
脏检查虽然可以达到实现双向绑定,但是当页面中绑定的 watcher 过多时,就会引发性能问题。所以 angular 在进行 $digest 检测时,会限制循环检查的次数最少2次,最多10次,防止无效的检查。
3.数据劫持 通过 ES5 的 Object.defineProperty() 来劫持数据属性的 getter 和 setter, 在数据变动时触发订阅者(watcher),从而触发相应的监听回调更新视图。
Observer 劫持了所有数据属性的 getter 和 setter,当数据发生改变时,就会通知 deps 中所有 watcher 的更新操作,进而触发页面的重新渲染,这是修改 Model 层从而引发 View 层的重新渲染。 在 Compile 中监听可输入元素的事件,然后将新值更新到 model 的数据中,这是修改 View 层触发的 Model 层的修改。
深拷贝和浅拷贝只针对象 Object, Array 这样的复杂对象(引用类型)的。
复制引用(引用类型)的拷贝方法称之为浅拷贝,创建一个新对象,这个对象有着原始对象属性值的一份精确拷贝。如果属性是基本类型,拷贝的就是基本类型的值,如果
属性是引用类型,拷贝的就是内存地址 ,所以如果其中一个对象改变了这个地址,就会影响到另一个对象。
深拷贝就是指完全的拷贝一个对象,将原对象的各个属性递归复制下来。这样即使嵌套了对象,两者也相互分离。
1 | var shallowCopy = function(obj) { |
具有循环引用的对象时,报错 当值为函数、undefined、或symbol时,无法拷贝
1 | // 不考虑循环引用 |
1 | // 不考虑循环引用 |
1 | // 考虑循环引用 只考虑了普通的 object和 array两种数据类型 |
1 | // 终极版 |
尽管使用深拷贝会完全的克隆一个新对象,不会产生副作用,但是深拷贝因为使用递归,性能会不如浅拷贝,在开发中,还是要根据实际情况进行选择。
typeof一般只能返回如下几个结果:number,boolean,string,function,object,undefined字符串
对于Array,null等特殊对象使用typeof一律返回object,这正是typeof的局限性。
typeof表示是对某个变量类型的检测,基本数据类型除了null都能正常的显示为对应的类型,引用类型除了函数会显示为’function’,其它都显示为object。
1 | var fn = new Function ('a', 'b', 'return a + b') |
instanceof适用于检测对象,它是基于原型链运作的。
instanceof 运算符用来测试一个对象在其原型链中是否存在一个构造函数的 prototype 属性。换种说法就是如果左侧的对象是右侧对象的实例, 则表达式返回true, 否则返回false 。
instanceof对基本数据类型检测不起作用,因为基本数据类型没有原型链。可以准确的判断复杂数据类型。
1 | [1, 2, 3] instanceof Array // true |
可以检测各种数据类型,推荐使用。
1 | Object.prototype.toString.call([]); // => [object Array] |
1 | let isType = type => obj => { |
constructor也不是保险的,因为constructor属性是可以被修改的,会导致检测出的结果不正确。
1 | console.log([].constructor === Array) // true |
今天10月31日,万圣节前夜。希望ff的病早点好,身体健康。
1 | var obj = {} // 字面量 |
黑科技JS代码整理 是不是很void 666
1 | "★★★★★☆☆☆☆☆".slice(5 - rate, 10 - rate);定义一个变量rate是1到5的值 |
1 | (!(~+[])+{})[--[~+""][+[]]*[~+[]] + ~~!+[]]+({}+[])[[~!+[]]*~+[]] |
1 | try { |
Babel 是一个工具链,主要用于将 ECMAScript 2015+ 版本的代码转换为向后兼容的 JavaScript 语法,以便能够运行在当前和旧版本的浏览器或其他环境中。Babel 内部所使用的语法解析器是 Babylon
一个基本的.babelrc配置:
1 | { |