前端总结之JavaScript篇

1.原型 / 构造函数 / 实例

原型( prototype ): ?个简单的对象,?于实现对象的 属性继承。可以简单的理解成对象的爹。在 Firefox 和 Chrome 中,每个 JavaScript 对象中都包含?个

proto (?标准)的属性指向它爹(该对象的原型),可  obj. proto 进?访问。构造函数: 可以通过 new 来 新建?个对象 的函数。

实例: 通过构造函数和  new 创建出来的对象,便是实例。 实例通过   proto 指向原

型,通过 constructor 指向构造函数。

以 Object 为例,我们常?的 Object 便是?个构造函数,因此我们可以通过它构建实例。

// 实 例

const instance = new Object()

则此时, 实例为 instance , 构造函数为 Object ,我们知道,构造函数拥有

?个 prototype 的属性指向原型,因此原型为:

// 原 型

const prototype = Object.prototype

这?我们可以来看出三者的关系:

实例. proto === 原 型

原型.constructor === 构造函数构造函数.prototype === 原型

// 这条线其实是是基于原型进?获取的,可以理解成?条基于原型的映射线

// 例如:

// const o = new Object()

// o.constructor === Object    --> true

// o. proto = null;

// o.constructor === Object    --> false

实例.constructor === 构造函数

2.原型链:

原型链是由原型对象组成,每个对象都有  proto

属性,指向了创建该对

象的构造函数的原型,    proto

将对象连接起来组成了原型链。是?个?

来实现继承和共享属性的有限的对象链

属性查找机制: 当查找对象的属性时,如果实例对象?身不存在该属性,则沿着原型链往上

?级查找,找到时则输出,不存在时,则继续沿着原型链往上?级查找,直?最顶级的原  型对象 Object.prototype ,如还是没找到,则输出 undefined ;

属性修改机制:  只会修改实例对象本身的属性,如果不存在,则进?添加该属性,如果需要修改原型的属性时,则可以?: b.prototype.x = 2 ;但是这样会造成所有继承于该对象

的实例的属性发?改变。

3.执?上下?(EC)

执?上下?可以简单理解为?个对象:

它包含三个部分:

变量对象( VO )

作?域链(词法作?域)

this 指 向

它的类型:

全局执?上下?

函数执?上下?

eval 执?上下?

代码执?过程:

创建 全局上下? ( global EC )

全局执?上下? ( caller ) 逐? ?上?下 执?。遇到函数时,函数执?上下?( callee ) 被 push 到执?栈顶层

函数执?上下?被激活,成为    active EC , 开始执?函数中的代码,  caller 被挂起函数

执?完后, callee 被 pop 移除出执?栈,控制权交还全局上下? ( caller ),继续执?

4.变量对象

变量对象,是执?上下?中的?部分,可以抽象为?种   数据作?域,其实也可以理解为就是?个简单的对象,它存储着该执?上下?中的所有 变量和函数声明(不包含函数表达

式)。

活动对象 ( AO ): 当变量对象所处的上下?为 active EC 时,称为活动对象。

5. 作?域

执?上下?中还包含作?域链。理解作?域之前,先介绍下作?域。作?域其 实可理解为该上下?中声明的 变量和声明的作?范围。可分为 块级作?域 和函数作?域

特性:

声明提前: ?个声明在函数体内都是可?的, 函数优先于变量

?匿名?执?函数,函数变量为 只读 状态,?法修改

js

let foo = function() { console.log(1) }

(function foo() {

foo = 10 // 由于foo在函数中只为可读,因此赋值?效

console.log(foo)

}())

// 结果打印: ƒ foo() { foo = 10 ; console.log(foo) }

6. 作?域链

我们知道,我们可以在执?上下?中访问到?级甚?全局的变量,这便是作?  域链的功劳。作?域链可以理解为?组对象列表,包含 ?级和?身的变量对象,因此我们便能通过作?域链访问到?级?声明的变量或者函数。

由两部分组成:

[[scope]] 属性: 指向?级变量对象和作?域链,也就是包含了?级的 [[scope]] 和 AO AO : ?身活动对象

如此 [[scopr]] 包含 [[scope]] ,便?上?下形成?条 链式作?域。

7. 闭包

闭包属于?种特殊的作?域,称为  静态作?域。它的定义可以理解为: ?函数被销毁 的情况下,返回出的?函数的 [[scope]] 中仍然保留着?级的单变量对象和作?域链,因此可以继续访问到?级的变量对象,这样的函数称为闭

闭包会产??个很经典的问题:

多个?函数的 [[scope]] 都是同时指向?级,是完全共享的。因此当?级的变量对象被修改时,所有?函数都受到影响。

••解决:**

变量可以通过 函数参数的形式 传?,避免使?默认的 [[scope]] 向上查找

使? setTimeout 包裹,通过第三个参数传?

使? 块级作?域,让变量成为??上下?的属性,避免共享

8.script 引??式:

html 静 态 <script> 引 ?

js 动态插? <script>

<script defer> : 异步加载,元素解析完成后执?

<script async> : 异步加载,但执?时会阻塞元素渲染

9. 对象的拷?

浅拷?: 以赋值的形式拷?引?对象,仍指向同?个地址,修改时原对象也会受到影响

Object.assign

展开运算符( ... )

深拷?: 完全拷??个新对象,修改时原对象不再受到任何影响

JSON.parse(JSON.stringify(obj)) : 性能最快具有循环引?的对象时,报错

当值为函数、 undefined 、或 symbol 时,?法拷?递归进?逐?赋值

10.new运算符的执?过程

新?成?个对象

链接到原型:  obj. proto = Con.prototype

绑 定 this: apply

返回新对象(如果构造函数有?? retrun 时,则返回该值)

new运算符的执?过程

新?成?个对象

链接到原型:  obj. proto = Con.prototype

绑 定 this: apply

返回新对象(如果构造函数有?? retrun 时,则返回该值)

11. instanceof原理

能在实例的 原型对象链 中找到该构造函数的 prototype 属性所指向的 原型对象,就返回 true 。即:

// proto : 代表原型对象链

instance.[ proto ...] === instance.constructor.prototype

// return true

j

12. 代码的复?

当你发现任何代码开始写第?遍时,就要开始考虑如何复?。?般有以下的?   式:

函数封装继承

复 制 extend

混? mixin

借 ? apply/call

13. 继承

在 JS 中,继承通常指的便是 原型链继承,也就是通过指定原型,并可以通过原型链继承原型上的属性或者?法。

最优化: 圣杯模式

var inherit = (function(c,p){
    var F = function(){};
    return function(c,p){
        F.prototype = p.prototype;
        c.prototype = new F();
        c.uber = p.prototype;
        c.prototype.constructor = c;
    }
})();

使? ES6 的语法糖 class / extends

14. 类型转换

?家都知道 JS 中在使?运算符号或者对?符时,会?带隐式转换,规则如下:

-、*、/、% :?律转换成数值后计算

+:

数字 + 字符串 = 字符串, 运算顺序是从左到右

数字 + 对象, 优先调?对象的 valueOf -> toString

数字 + boolean/null -> 数字数 字 + undefined -> NaN

[1].toString() === ‘1‘

{}.toString() === ‘[object object]‘ NaN !== NaN 、+ undefined 为 NaN

15. 类型判断

判断    Target 的类型,单单?    typeof 并?法完全满?,这其实并不是bug ,本质原因是  JS 的万物皆对象的理论。因此要真正完美判断时,我们需要区分对待:

基本类型( null ): 使? String(null)

基本类型( string / number / boolean / undefined ) + function : - 直接使?typeof 即 可

其余引?类型( Array / Date / RegExp Error ): 调? toString 后根据 [object XXX] 进?判断

很稳的判断封装:

j

let class2type = {}

‘Array Date RegExp Object Error‘.split(‘ ‘).forEach(e => class2type[ ‘[obje

function type(obj) {

    if (obj == null) return String(obj)

    return typeof obj === ‘object‘ ? class2type[Object.prototype.toString.

}

16. 模块化

模块化开发在现代开发中已是必不可少的?部分,它??提?了项?的可维护、可拓展和可协作性。通常,我们 在浏览器中使? ES6 的模块化?持,在Node 中使? commonjs 的模块化?持。

分类:

es6: import / export

commonjs: require / module.exports / exports

amd: require / defined

require与import的区别

require ?持 动态导?, import 不?持,正在提案 ( babel 下可?持)

require 是 同步 导?, impor t属于 异步 导?

require 是 值拷?,导出值变化不会影响导?值; import 指向 内存地址,导?值会随导出值?变化

17. 防抖与节流

防抖与节流函数是?种最常?的 ?频触发优化?式,能对性能有较?的帮助。

防抖 (debounce): 将多次?频操作优化为只在最后?次执?,通常使?的场景是:?户输

?,只需再输?完成后做?次输?校验即可。

function debounce(fn, wait, immediate) {

    let timer = null

    return function() {

        let args = arguments
        let context = this

        if (immediate && !timer) { 

            fn.apply(context, args)

        }

        if (timer) clearTimeout(timer) 

        timer = setTimeout(() => {

            fn.apply(context, args)

        }, wait)

    }

}        

节流(throttle): 每隔?段时间后执??次,也就是降低频率,将?频操作优化成低频操作, 通常使?场景: 滚动条事件 或者 resize 事件,通常每隔 100~500 ms 执??次即可。

js

function throttle(fn, wait, immediate) {

    let timer = null

    let callNow = immediate

     return function() {

        let context = this, args = arguments

        if (callNow) {

            fn.apply(context, args) callNow = false

        }

        if (!timer) {

            timer = setTimeout(() => {

                fn.apply(context, args) timer = null

            }, wait)

        }

    }

}

18.函数执?改变this

由于 JS 的设计原理: 在函数中,可以引?运?环境中的变量。因此就需要?个机制来让我们可以在函数体内部获取当前的运?环境,这便是 this 。

因此要明? this 指向,其实就是要搞清楚 函数的运?环境,说?话就是, 谁调?了函数 例如

obj.fn() ,便是 obj 调?了函数,既函数中的 this === obj fn() ,这?可以看成 window.fn() ,因此 this === window

但这种机制并不完全能满?我们的业务需求,因此提供了三种?式可以?动修  改 this 的 指 向 :

call: fn.call(target, 1, 2)

apply: fn.apply(target, [1, 2])

bind: fn.bind(target)(1,2)

19. ES6/ES7

由于 Babel 的强?和普及,现在 ES6/ES7 基本上已经是现代化开发的必备了。通过新的语法糖,能让代码整体更为简洁和易读。

声明

let / const : 块级作?域、不存在变量提升、暂时性死区、不允许重复声明

const : 声明常量,?法修改

解构赋值

class / extend: 类声明与继承

Set / Map: 新的数据结构

异步解决?案:

Promise 的使?与实现

generator :

yield : 暂停代码

next() : 继续执?代码

function* helloWorld() {

    yield ‘hello‘;
    yield ‘world‘;
    return ‘ending‘;

}

const generator = helloWorld();

generator.next()    // { value: ‘hello‘, done: false }
generator.next()    // { value: ‘world‘, done: false }
generator.next()    // { value: ‘ending‘, done: true } generator.next()    // { value: undefined, done: true }

await / async : 是 generator 的语法糖, babel 中是基于 promise 实现。

async function getUserByAsync(){ 

    let user = await fetchUser();
    return user;

}

const user = await getUserByAsync() console.log(user)

20. AST

抽象语法树 ( Abstract Syntax Tree ),是将代码逐字?解析成 树状对象 的形式。这是语?之间的转换、代码语法检查,代码?格检查,代码格式化,代  码?亮,代码错误提示,代码?动补全等等的基础。例如:

js

function square(n){ 

    return n * n

}

通过解析转化成的AST如下图:

21.babel编译原理

babylon 将 ES6/ES7 代码解析成 AST

babel-traverse 对 AST 进?遍历转译,得到新的 AST

新 AST 通过 babel-generator 转换成 ES5

22. 函数柯?化

在?个函数中,?先填充?个参数,然后再返回?个新的函数的技术,称为函 数的柯?化。通常可?于在不侵?函数的前提下,为函数 预置通?参数,供多次重复调?。

const add = function add(x) { 

    return function (y) {

        return x + y

    }

}

const add1 = add(1)

add1(2) === 3

add1(20) === 21

23.数组(array)

map : 遍历数组,返回回调返回值组成的新数组

forEach : ?法 break ,可以? try/catch 中 throw new Error 来停?

filter : 过滤

some : 有?项返回 true ,则整体为 true

every : 有?项返回 false ,则整体为 false

join : 通过指定连接符?成字符串

push / pop : 末尾推?和弹出,改变原数组, 返回推?/弹出项

unshift / shift : 头部推?和弹出,改变原数组,返回操作项

sort(fn) / reverse : 排序与反转,改变原数组

concat : 连接数组,不影响原数组, 浅拷?

slice(start, end) : 返回截断后的新数组,不改变原数组

splice(start, number, value...) : 返回删除元素组成的数组, value 为插?项,改

变原数组

indexOf / lastIndexOf(value, fromIndex) : 查找数组项,返回对应的下标

reduce / reduceRight(fn(prev, cur) , defaultPrev) : 两两执?, prev 为上次化简函数的 return 值, cur 为当前值(从第?项开始)

数组乱序:

var arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];

arr.sort(function () {

    return Math.random() - 0.5;

});

数组拆解: flat: [1,[2,3]] --> [1, 2, 3]

Array.prototype.flat = function() {

     this.toString().split(‘,‘).map(item =>  +item )

}    

j

原文地址:https://www.cnblogs.com/yongbin668/p/12194589.html

时间: 2024-10-09 15:30:57

前端总结之JavaScript篇的相关文章

前端知识点回顾——Javascript篇(六)

fetch 在原生ajax+es6promise的基础上封装的一个语法糖,返回promise对象. fetch(url, initObj) .then(res=>res.json()) .then(data=>{ //这里得到返回的json对象,可进行操作 }) .cateh(err){ console.log(err); }; //initObj { body: JSON.stringify(data), // must match 'Content-Type' header cache:

关于前端开发的20篇文档与指南-转

关于前端开发的20篇文档与指南 前端开发开发者CSSJavaScriptHTMLWeb 摘要:前端开发者中相信很多人会有两种感受:真的不知所措,这个行业到底有多少东西需要去学习:渴望更多,并迫不及待的为接下来的学习寻求一些思想方向.本文整理一些有用的信息,希望可以帮助相关领域的前端开发人员. 相信在2015年很多这个行业的人都会有这样的两种感受: 真的不知所措,这个行业到底有多少东西需要去学习: 渴望更多,并迫不及待的为接下来的学习寻求一些思想方向. 第一个来自于我们的个人感受,而第二个则是纯粹

前端深入之css篇丨2020年前,彻底掌握css动画【transition】

原文:前端深入之css篇丨2020年前,彻底掌握css动画[transition] 写在前面 马上就2020年了,不知道小伙伴们今年学习了css3动画了吗? 说起来css动画是一个很尬的事,一方面因为公司用css动画比较少,另一方面大部分开发者习惯了用JavaScript来做动画,所以就导致了许多程序员比较排斥来学习css动画(至少我是),但是一个不懂css动画的前端工程师不能称之为掌握css3,其实当你真正学习css动画之后,你会被它的魅力所吸引的,它可以减少代码量.提高性能. 话不多说,马上

前端深入之css篇丨初探【transform】,手把手带你实现1024程序员节动画

原文:前端深入之css篇丨初探[transform],手把手带你实现1024程序员节动画 写在前面 马上就2020年了,不知道小伙伴们今年学习了css3动画了吗? 说起来css动画是一个很尬的事,一方面因为公司用css动画比较少,另一方面大部分开发者习惯了用JavaScript来做动画,所以就导致了许多程序员比较排斥来学习css动画(至少我是),但是一个不懂css动画的前端工程师不能称之为掌握css3,其实当你真正学习css动画之后,你会被它的魅力所吸引的,它可以减少代码量.提高性能. 值此10

前端深入之css篇丨2020年前,彻底掌握css动画【animation】

原文:前端深入之css篇丨2020年前,彻底掌握css动画[animation] 写在前面 马上就2020年了,不知道小伙伴们今年学习了css3动画了吗? 说起来css动画是一个很尬的事,一方面因为公司用css动画比较少,另一方面大部分开发者习惯了用JavaScript来做动画,所以就导致了许多程序员比较排斥来学习css动画(至少我是),但是一个不懂css动画的前端工程师不能称之为掌握css3,其实当你真正学习css动画之后,你会被它的魅力所吸引的,它可以减少代码量.提高性能. 上一篇文章我们已

20170917 前端开发周报:JavaScript函数式编程、作用域和闭包

1.用函数式编程对JavaScript进行断舍离 当从业20的JavaScript老司机学会函数式编程时,他扔掉了90%的特性,也不用面向对象了,最后发现了真爱啊!!! https://juejin.im/entry/59b86... 2.JavaScript作用域和闭包 作用域和闭包在JavaScript里非常重要.但是在我最初学习JavaScript的时候,却很难理解.这篇文章会用一些例子帮你理解它们.我们先从作用域开始.作用域 JavaScript的作用域限定了你可以访问哪些变量.有两种作

javascript篇:javascript对象——Math

Math对象用于执行数学任务,无需创建它的实例: var mathPI = Math.PI; var myVal = Math.sqrt(4); Math对象的属性 E:返回算术常量e,约等于2.718 LN2:返回2的自然对数,约等于0.693 LN10:返回10的自然对数,约等于2.302 LOG2E:返回以2为底的e的对数,约等于1.414 LOG10E:返回以10为底的e的对数,约等于0.434 PI:返回圆周率,约等于3.14159 SQRT1_2:返回2的平方根的倒数,约等于0.70

前端html、Javascript、CSS技术小结

简单地总结了一下前端用过的html.javascript.css技术,算是清点一下,做个大略的小结,为进一步的学习给个纲领. 一.HTML 由于HTML5的兴起,简单地判断一个网页是否是html5网页,只需要找找内部是否有html5的标志性标签就行了.然而平时虽然写了不少html,却没怎么关注它的发展史: GML(Generalized Marcup Language)通用标记语言 和SGML(Standard Generalized Markup Language)标准通用标记语言. 由Tim

javascript篇:javascript对象——Date

Date对象是javascript的内置对象,用于处理日期和时间,使用前必须定义: var myDate = new Date();//Date对象会自动初始化该对象,使其值为当前日期和时间. var myDate = new Date("June 15, 1990 00:00:00"); var myDate = new Date(milsec);//参数为距离1970/1/1午夜的毫秒数 以上方式定义myDate 是本地时间,而不是UTC时间. Date对象的属性: constru