JS高级

1. 访问对象属性(方法也是属性)的通用方式:obj['属性名']
1. 属性名包含特殊字符,如"-"、空格,访问:obj['content-type']
2. 属性名不确定:var name='age'; var value=18; obj[name]=value
2. IIFE:立即执行函数,用于隐藏实现、避免污染全局命名空间、编写JS模块
(function(){ ... })() ---> 即匿名函数自调用
3. this的指向
1. 任何函数本质上都是通过某个对象来调用的,如果没有显式指定,则默认是window;
2. 所有函数内部都有一个变量this,指向当前调用函数的对象;
3. functionName.call()/apply():第一个参数用于指定函数内部this的指向。
4. JS语句可以不加分号,但有2种情况必须加分号:
1. 小括号开头的前一条语句;
var a = 3;
(function() { ... })()
2. 中方括号开头的前一条语句;
var b = 4;
[1, 3].forEach(function)
3. 为了避免这2种错误,可以在行首加分号:;(function() { ... })()

原型

function Test() { ... }
1. prototype:显式原型(属性)
1. 定义函数时自动添加一个prototype属性,默认指向一个Object空对象,即原型对象;
Test.prototype instanceof Object --> true
Function.prototype instanceof Object --> true
Object.prototype instanceof Object --> false,Object除外
2. 原型对象中又有一个属性constructor,指向函数自身;
Test.prototype.constructor === Test ---> true
3. 给原型对象添加属性/方法,函数的所有实例对象自动拥有原型对象中的属性/方法。
2. __proto__:隐式原型(属性),ES6之前不能直接操作该属性
1. 创建实例对象时自动添加一个__proto__属性,默认值为构造函数的prototype属性值;
即:实例对象的隐式原型和构造函数的显式原型指向同一个原型对象;
var tes = new Test();
tes.__proto__ === Test.prototype ---> true
2. 函数也有隐式原型,而且所有函数(包括Object和Function)都是Function的实例;
Test/Object/Function.__proto__ === Function.prototype ---> true
3. 原型链:__proto__链
1. 原型对象中也有隐式原型__proto__,指向当前构造函数的父构造函数的原型对象;
tes.show() --> 自身 --> 沿着__proto__查找:tes.__proto__ 即Test.prototype
--> Test.prototype.__proto__ 即Object.prototype --> show()不存在,报错;
2. 所有对象/构造函数,包括Function,都直接/间接派生自Object,它是JS的顶层父类,
其原型对象就是原型链的尽头,因为Object.prototype.__proto__ === null
4. 访问对象属性/方法时,会自动到原型链上查找;而设置对象的属性值时,则不会涉及原型链,
如果对象中没有该属性/方法,则添加,否则就修改;
5. 一般情况下,方法定义在原型中,属性直接定义在通过构造函数;
6. A instanceof B 的判断的标准:如果B的显示原型在A的原型链上,则返回true.

函数高级

1. 全局执行上下文
1. 在执行全局代码前,将window确定为全局执行上下文;
2. 对全局数据进行预处理:var定义的全局变量会被提前声明(值为undefined),全局函数
会被提前定义,并把全局变量/函数添加为window的属性/方法;
3. this指向window;
4. 在执行代码时,才会对变量重新赋值,而定义函数的代码会直接跳过,因为在执行全局
代码之前,函数已经被提前定义了。
var test = 1;
function test() { ... }
test(); ---> 报错:test is not a function
5. 真正的执行过程:
var test; --> function test() { ... } --> test = 1; --> test();
2. 函数执行上下文
1. 调用函数、准备执行函数之前,创建对应的函数执行上下文;
2. 对局部数据做预处理:变量的提前声明,函数的提前定义,this的指向,形参的赋值等;
3. 闭包:内部函数引用外部函数的局部变量,外部函数执行完后,其局部变量仍存活于内存中;
function out() {
var a = 2;
function inner() {
console.log(++a);
}
return inner;
}
1. var f = out(); --> 变量f持有内函数inner()的引用,所以局部变量a仍在内存中;
2. out(); --> 没有任何引用内函数指向inner(),那么inner将成为垃圾对象,并被GC;
也即,局部变量a也不存在了;
3. 闭包的生命周期:在函数内部定义时就已经产生了,在内部函数成为垃圾对象时死亡;
var f = out(); --> f(); --> f = null; --> 死亡,释放内存;
4. 闭包容易造成内存泄露,应该及时释放。
4. 利用闭包自定义JS模块-1:myModule.js
function myModule() {
var msg = 1;
function showMsg() { ... }
return showMsg; --> 向外暴露
}
在html中引用:<script src="myModule.js" type="text/javascript">
var fn = myModule(); --> fn指向内部函数showMsg() --> 执行showMsg():fn();
如果暴露多个函数,则返回一个对象:return { showMsg: showMsg, }
var module = myModule(); --> 执行showMsg():module.showMsg();
5. 利用闭包自定义JS模块-2:myModule.js
(function(w) { --> 自执行函数
var msg = 1;
function showMsg() { ... }
w.myModule = { showMsg: showMsg, } --> 向外暴露
})(window) --> 为全局上下文window添加属性myModule
在html中引用:<script src="myModule.js" type="text/javascript">
myModule.showMsg(); --> myModule是window的属性,可以直接使用;

对象高级

1. 创建对象:
1. Object构造函数模式:var obj = new Object(); --> 然后为对象添加属性/方法;
2. 对象字面量模式:var obj = { ...(属性/方法) }
3. 工厂模式:动态返回一个对象的函数;
4. 自定义构造函数模式:var obj = new Person('Mack')
function Person(name) {
this.name = name;
this.show = function() { ... }
}
5. 构造函数+原型的组合模式:
function Person(name) { this.name=name; }
Person.prototype.show = function() { ... } --> 公共的方法定义在原型对象中
2. 原型链继承:子类的原型是父类的一个原型对象;
1. 定义父类构造函数,并在原型中添加方法;
function Supper() { this.supProp = 'Supper property'; }
Supper.prototype.showSupper = function() { ... }
2. 定义子类构造函数,让子类的原型指向父类对象,修正子类原型对象中的constructor,
让其指向子类构造函数,然后为子类的原型添加方法;
function Sub() { this.subProp = 'Sub property'; }
Sub.prototype = new Supper(); --> 更改显示原型的指向
Sub.prototype.constructor = Sub; --> 修正constructor的指向
//Sub.prototype.__proto__即new Supper().__proto__,指向Supper.prototype
Sub.prototype.showSub = function() { ... }
3. 创建子类的对象,可以调用父类的方法:var sub = new Sub();
sub.showSubProp(); sub.showSupperProp();

本地存储

cookie,H5新增的localStorage、sessionStorage

cookie

1. 存储在浏览器的一段文本信息,最大容量4k,在同源的http请求时携带传递,损耗带宽;
2. cookie是在服务器端设置的,浏览器接收到cookie信息,便以键-值的形式存储在本地;
3. 出于安全考虑,跨域名请求不会携带cookie,这是由浏览器技术实现的安全策略;
4. 可设置访问路径和过期时间,只有此路径及其子路径才能访问此cookie。

localStorage

1. 容量最小5M,不会在http请求时携带传递,不需要服务器环境;
2. 在所有同源窗口中共享,数据始终有效,除非人为删除,可作为长期数据;
3. 设置:localStorage.setItem('key', 'value'); localStorage.key = value;
4. 获取:localStorage.getItem('key'); localStorage.key;
5. 删除:localStorage.removeItem('key');

sessionStorage

1. 容量最小5M,不会在http请求时携带传递,在同源的当前窗口关闭前有效;
2. 与localStorage合称为Web Storage,支持事件通知机制,可以将数据更新通知监听者;
3. iPhone的无痕浏览不支持Web Storage,只能用cookie.

JS与后台通信

AJAX:同源策略

1. JS原生支持AJAX,目的是让JS发送HTTP请求,且AJAX通信的过程是异步的;
2. 同源策略:基于安全考虑,AJAX只能请求同一域名下的资源,通常是JSON数据;
报错特征:No 'Access-Control-Allow-Origin' header is present
on the requested resource. Origin 'null' is therefore not allowed access.
3. AJAX执行的是同源策略,所以请求的url不需要域名,比如 url: 'js/user.json';

JSONP:跨域请求

1. 原理:<script src="..."> src链接的地址不受限制;
2. 在页面上定义的JS函数,script-src链接的外部JS文件也可以调用,那么,外部JS就可以
把数据以回调参数的形式传递回当前页面。

移动端JS事件

1. 移动端主要用手指操作,在JS中对应Touch事件:
1. touchstart/touchend/touchmove:手指放到屏幕上/离开屏幕/滑动时触发;
2. touchcancel:系统取消Touch事件时触发;
3. 移动端一般操作:点击、滑动、拖动,这三种操作一般组合使用Touch事件完成。
2. zeptojs:最初是为移动端提供一个精简的、类似jQuery的JS库,现在发展成一个轻量级的、
针对现代高级浏览器的JS库;
1. API类也似于jQuery,比如$(function(){ ... })、$(this)、$('#div') ...
2. 其touch模块封装了移动端常用的Touch事件,针对开发移动端的特定效果。
3. swiper.js:一个成熟稳定的、应用于PC端和移动端的滑动效果插件;
1. 一般用来触屏焦点图、触屏整屏滚动、幻灯片等效果;
2. 2.x版本支持低版本浏览器IE7,3.x放弃低版本浏览器,适用于移动端。

进程与线程

1. 作为浏览器脚本语言,JS主要与用户交互及操作DOM,这决定了JS是单线程的,效率高;
2. H5中的Web Workers可以多线程运行;
3. 浏览器是多线程运行的,Firefox、老版IE是单进程,新版IE、Chrome是多进程;
4. 浏览器内核:支撑浏览器运行的核心程序,由很多模块组成;
1. Chrome/Safari:webkit Firefox:Gecko IE:Trident
2. 360、搜狗等国内浏览器的内核:Trident+webkit
3. 内核模块-主线程:JS引擎模块(JS的编译与运行),HTML文档解析模块,DOM/CSS模块
(DOM/CSS在内存中的相关处理),布局和渲染模块(负责页面的布局和效果的绘制)...
4. 内核模块-子线程:定时器模块(管理定时器),事件响应模块(管理事件),网络请求模块
(AJAX请求)...

JS是单线程

1. 定时器机制:
1. 定时器并不能保证真正的定时执行,一般会延迟一点点,但也有可能延迟很长时间;
2. 定时器其实是在主线程中执行的,因为JS是单线程的,如果定时器执行前做耗时/阻塞的
操作,那么就可能造成定时器延迟很长时间。
2. JS代码分为初始化代码、回调代码,JS引擎执行代码的基本流程:
1. 先执行初始化代码:包括设置定时器、绑定监听、发送AJAX请求
2. 在后面的某个时刻才会执行回调代码;
3. 弹出alert,JS代码是阻塞的,计时也会被暂停,定时器随之被延迟,直到关闭alert后
才会恢复计时,执行定时器。
3. 事件驱动模型
1. event loop:事件轮询,事件包括定时器、DOM事件、AJAX
2. callback queue:事件的回调队列,存放待处理的回调函数;
3. 当事件发生时,管理模块会将回调函数及其数据添加到回调队列中,等待主线程执行。

Web Workers

1. JS是单线程的,在做耗时的操作时,如大量计算,Web界面就会卡死;
2. Web Workers是H5提供的一个JS多线程解决方案,子线程完全受主线程控制,由子线程去执行
耗时的计算,避免冻结主线程,但H5不允许子线程操作DOM,所以并没有改变JS单线程的本质;
3. 使用Web Workers:
1. 创建子线程执行的JS文件:worker.js
var onmessage = function(event) { --> 接收主线程发来的消息,var可省略
var data = event.data
postMessage('Hello Main') --> 向主线程发消息
}
2. 在主线程中的JS中发消息,并设置回调:
var worker = new Worker('worker.js')
worker.onmessage = function(event) { --> 监听子线程发来的消息
var data = event.data --> 获取子线程发来的数据
}
worker.postMessage('Hello Worker'); --> 向子线程发送消息
4. 主线程的全局上下文是window,而子线程的全局上下文DedicatedWorkerGlobalScope
1. DedicatedWorkerGlobalScope的属性/方法:
onmessage: null,postMessage: function,close: function ...
2. 子线程的全局上下文对象中没有alert()、document等,所以子线程中不能更新界面。
5. Web Workers的缺点:慢,不能跨域加载JS,不能操作DOM,有些浏览器不支持。

自动化与优化

1. less、sass、stylus:三种样式动态语言,属于CSS预处理语言,便于CSS的编写和维护;
1. 有类似于CSS的语法,赋予CSS动态语言的特性,如变量、继承、函数等;
2. 文件后缀分别是:x.less、x.scss、x.styl,并不能直接使用,需要编译成CSS文件;
3. 编译方式:软件编译如koala,或者用nodejs程序编译,如grunt、gulp
2. gulp比grunt更简洁、性能更高,gulp的常用插件:
1. 压缩JS代码gulp-uglify、less的编译gulp-less、CSS的压缩gulp-minify-css.
2. 自动添加CSS3前缀gulp-autoprefixer、文件重命名gulp-rename.

性能优化

1. 代码部署
1. 代码的压缩与合并:去除空格、换行等,可利用gulp工具的插件完成;
2. 图片、JS、CSS等静态资源存储在与主站不同的域名地址,避免在传输时携带cookie;
3. 权衡DNS查找次数,使用不同域名会增加DNS查找;与上述相违背,权衡处理;
4. 使用内容分发网络 CDN;使用GZIP压缩传输,压缩效率高;
5. 为文件设置Last-Modified、Expires和Etag,即本地缓存数据;
6. 避免不必要的重定向,在链接末尾手动加"/",如https://www.baidu.com/
2. HTML:避免空的src和href,不要在HTML中缩放图片。
3. CSS
1. 精简CSS选择器的层级,并把CSS放到顶部,避免@import的方式引入样式;
2. 使用Base64编码的图片数据取代图片文件,减少请求次数;
3. 使用CSS动画来取代JS动画,CSS动画是虚拟完成的,并不会改变页面结构;
4. 使用字体图标:https://fontawesome.com/icons
5. 使用CSS Sprite雪碧图,SVG图像;避免使用CSS表达式和滤镜。
4. JavaScript
1. 减少引用库的个数,使用模块化概念的requerejs/seajs异步加载JS;
2. JS在加载时会阻塞页面继续向下解析,理论上JS应该放在页面底部引用;
3. 避免全局查找,约束范围去查找;减少属性查找;尽可能使用原生方法;
4. 用switch代替复杂的if-else;减少语句数,比如多个变量声明可以合成一句;
5. 使用字面量表达式来初始化数组/对象,比如arr=[1,2,3]取代new Array(1,2,3);
6. 使用DocumentFragments/innerHTML取代复杂的元素注入;
7. 使用事件代理/委托;高频触发的事件设置函数节流;
8. 避免多次dom选择集,使用变量存储,var d = $('#div');
9. 使用Web Storage缓存数据;使用Array的join()取代字符串的"+"连接。

JS高级(摘自简书)的更多相关文章

  1. 前端进阶试题css(来自js高级前端开发---豪情)既然被发现了HOHO,那我就置顶了嘿嘿!觉得自己技术OK的可以把这套题目做完哦,然后加入高级前端的社区咯

    http://www.cnblogs.com/jikey/p/4426105.html js高级前端开发加群方法(此群很难进,里面纯技术,严禁广告,水群) 完整题目做完发邮箱(jikeytang@16 ...

  2. 从刚刚「简书」平台的短暂异常,谈Nginx An error occurred报错~

    09.26简书平台的短暂异常 An error occurred. Sorry, the page you are looking for is currently unavailable. Plea ...

  3. 读JS高级——第五章-引用类型 _记录

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  4. js实现中文简繁切换效果

    html代码: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www ...

  5. Ext.js高级组件

    第二章:Ext.js高级组件 grid组件 普通方式 表格面板类Ext.grid.Panel xtype(别名):gridpanel.grid title标题.renderTo渲染至.width宽.h ...

  6. jsoup爬虫简书首页数据做个小Demo

    代码地址如下:http://www.demodashi.com/demo/11643.html 昨天LZ去面试,遇到一个大牛,被血虐一番,发现自己基础还是很薄弱,对java一些原理掌握的还是不够稳固, ...

  7. 论wpf的设备无关性 - 简书

    原文:论wpf的设备无关性 - 简书 WPF从发布之日起,一直将“分辨率无关(resolution independence)”作为其亮点,声称使用WPF制作的用户界面在轻巧的Ultra-Mobile ...

  8. js如何实现简繁体互转

    js如何实现简繁体互转 一.总结 一句话总结:其实无论是简体还是繁体,都是在显示端(前端),其实所有的我只用动js就好了,没必要动php. 当然,后端也可以做前端的事情,只是麻烦了点(要多通信两次,第 ...

  9. Cordova 代码热更新 - 简书

    原文:Cordova 代码热更新 - 简书 Cordova 代码热更新 [图片上传失败...(image-a19be7-1521624289049)] 基于 Cordova 框架能将网页应用 (js, ...

随机推荐

  1. 单页面(如react,vue)网站的服务器渲染 SSR 之 SEO 大杀器 Rendertron

    单页面网站,比如vue.recat框架的网站,一般都是直接从服务器推送index.html,再根据自身路由通过js在客户端浏览器渲染出完整的html页面. 但是搜索引擎的爬虫可没有这么智能(实际上go ...

  2. iDevice取证的一大突破

    近日手机取证领域传出令人震撼的消息,知名取证大厂Cellebrite宣称可破解任何版本,任何机型的iDevice,连最新的iPhone X也逃不过. 若真属实,代表着iOS的取证又重现光明.只是不确定 ...

  3. JAVA常用的集合类

    package com.xian.test; import java.util.ArrayList; import java.util.Enumeration; import java.util.Ha ...

  4. Zabbix利用Windows性能监视器监控各项资源指标

    zabbix自带的windows监控模板并没有监控windows cpu使用率的监控 在cmd命令输入perfmon 打开后默认就一项CPU占用的监控,下面以添加硬盘空闲时间做示例 1:监控图形上面右 ...

  5. jQuery插件之路(一)——试着给jQuery的一个Carousel插件添加新的功能

    前几日在网上看到了一个关于Carousel插件的教学视频,于是也顺便跟着学习着做了一下.但是在做完之后发现,在别的网站上面看到类似的效果要比现在做的这个要多一个功能,也就是在底下会有一些按钮,当鼠标放 ...

  6. 【Java例题】5.5 两个字符串中最长公共子串

    5. 查找两个字符串中含有的最长字符数的公共子串. package chapter5; import java.util.Scanner; public class demo5 { public st ...

  7. C#使用LitJson解析Json数据

    //接受MQ服务器返回的值 private void jieshou(string zhiling, string can1, string can2, string can3, string can ...

  8. CSS3: perspective 3D属性

    本文引自:http://blog.csdn.net/cddcj/article/details/52956540 perspective 属性指定了观察者与z=0平面的距离,使具有三维位置变换的元素产 ...

  9. 鲜为人知的maven标签解说

    目录 localRepository interactiveMode offline pluginGroups proxies servers mirrors profiles 使用场景 出现位置 激 ...

  10. Stream和方法引用

    1.Stream流 1.for循环带来的弊端 在jdk8中,lambda专注于做什么,而不是怎么做 for循环的语法就是怎么做 for循环的循环体才是做什么 遍历是指每一个元素逐一进行处理,而并不是从 ...