rxjs
https://cn.rx.js.org/manual/tutorial.html
js 数组数字排序。(数组sort默认是字符串排序)
1 | a = Array.of(32,286,125,192,28,41,297,413,29,64,80,4).sort((a,b)=>a-b) |
控制台导入jq发送ajax
https://zju.date/ajax-request-in-chrome-console/
不使用contentType: “application/json”则data可以是对象
fetch1
2
3
4
5
6
7
8fetch("http://localhost:3000",{ // post请求
method:"POST",
headers: {
"Content-Type": "application/json"
},
body:'{"welcome":"你好"}'
}).then(res => console.log(res.json()))
.catch(e=>console.log("something went wrong: " + e))
使用contentType: “application/json”则data只能是json字符串1
2
3
4
5
6
7
8
9
10
11
12
13
14var jq = document.createElement('script');
jq.src = 'http://7xsy2w.com1.z0.glb.clouddn.com/jquery-3.1.1.min.js'; //也可以放本地服务器上
document.getElementsByTagName('head')[0].appendChild(jq);
j=jQuery
j.noConflict();
j.ajax({
url: 'http://localhost:8080/test/',
type: "POST",
data: usr,
contentType:"application/json;charset=utf-8",
dataType: "json",
success:function() {console.log('发送成功!'); },
error:function() { console.log('发送失败!'); }
});
手机端查看页面
npm install http-server -g
http-server
prototype
http://prototypejs.org/learn/event-delegation.html
js unicode->中文
1 | unescape(''); |
h5视频控制
到指定位置并播放1
2
3
4
5var v = document.getElementsByTagName("video")[0];
v.currentTime = 10.0;
v.play()
//暂停
v.pause()
html5存储
Content-Length 单位是字节
DnionOS nginx?
cookie 4k
document.cookie
cookies会有主域名污染
在.baidu.com放了cookie之后music子域名访问都带主域名的cookies,请求头会臃肿
http-only cookie只能被服务器端读写,客户端无权限。
Secure 请求只能是https
单个域名持支的cookie个数。chrome50个,长度4k
与localStorage类似 不同域名独立。
可以设置cookie的path和domain相同父域共享
H5之前userData 只有IE,存放成XML
indexedDB 按域名分配独立空间,一个域名多个数据库
H5离线缓存 manifest
navigator.onLine
检测是否在线1
<html lang = "en" manifest = 'manifestFile'>
manifestFile文件1
2
3
4
5CACHE MANIFEST
#version 1.1
CACHE:
img/1.jpg
NETWORK
1 | window.addEventListener('load',function(e){ |
改manifest版本号会更新
本地存储 子域名不能共享
h5 postMessage 共享数据
只有5个api:setItem/getItem/removeItem/clear/key
ios的隐身模式没有,需要检测浏览器支持,最好的方法是先set一次1
2
3
4localStorage.setItem('testkey','testvalue')
localStorage.getItem('testkey')
localStorage.key(9)
localStorage.clear()
localstorage 永不过期
sessionstorage 重新打开页面/关闭浏览器 消失
每个 域名5M
localStroage在chrome限制为2.6M 同域名一般共享
所有可以序列化的都能存到localStorage
存图片set('key')
+get('key')
1 | var src = "./bd_logo1.png" |
业务代码添加过期控制
set('wait4expire','expire')
,get('wait4expire',60*5*1000)
1 | function set(key,v){ |
- HTTP文件缓存
Application-Frames
Etag响应/if-Node-Match请求
同时设置Expire和Cache-Control只有Cache-Control生效
浏览器缓存
https://segmentfault.com/a/1190000009638800
Connection
https://imququ.com/post/transfer-encoding-header-in-http.html
HTTP/1.0 的持久连接机制是后来才引入的,通过 Connection: keep-alive 这个头部来实现,服务端和客户端都可以使用它告诉对方在发送完数据之后不需要断开 TCP 连接,以备后用。HTTP/1.1 则规定所有连接都必须是持久的,除非显式地在头部加上 Connection: close。所以实际上,HTTP/1.1 中 Connection 这个头部字段已经没有 keep-alive 这个取值了,但由于历史原因,很多 Web Server 和浏览器,还是保留着给 HTTP/1.1 长连接发送 Connection: keep-alive 的习惯。
浏览器可以通过 Content-Length 的长度信息,判断出响应实体已结束。那如果 Content-Length 和实体实际长度不一致会怎样?有兴趣的同学可以自己试试,通常如果 Content-Length 比实际长度短,会造成内容被截断;如果比实体内容长,会造成 pending。
TTFB(Time To First Byte),它代表的是从客户端发出请求到收到响应的第一个字节所花费的时间。
在头部加入 Transfer-Encoding: chunked 之后,就代表这个报文采用了分块编码。这时,报文中的实体需要改为用一系列分块来传输。每个分块包含十六进制的长度值和数据,长度值独占一行,长度不包括它结尾的 CRLF(\r\n),也不包括分块数据结尾的 CRLF。最后一个分块长度值必须为 0,对应的分块数据没有内容,表示实体结束。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16require('net').createServer(function(sock) {
sock.on('data', function(data) {
sock.write('HTTP/1.1 200 OK\r\n');
sock.write('Transfer-Encoding: chunked\r\n');
sock.write('\r\n');
sock.write('b\r\n');
sock.write('01234567890\r\n');
sock.write('5\r\n');
sock.write('12345\r\n');
sock.write('0\r\n');
sock.write('\r\n');
});
}).listen(9090, '127.0.0.1');
webworkers
《高性能网站建设进阶指南》
https://www.html5rocks.com/en/tutorials/workers/basics/1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 var worker = new Worker("./worker.js")
console.log("主线程主线程主线程主线程1")//1
worker.addEventListener("message",function(e){
console.log("主线程主线程主线程主线程2")//8
console.log("worker said",e.data)//9
console.log("主线程主线程主线程主线程3")//10
},false)
console.log("主线程主线程主线程主线程4")//2
worker.postMessage("hello world");
console.log("主线程主线程主线程主线程5")//3
//worker.js
console.log("子线程0")//4
self.addEventListener("message",function(e){
console.log("子线程1")//6
self.postMessage(e.data)
console.log("子线程2")//7
},false)
console.log("子线程3")//5
fisher-yates 洗牌
shuffle the deck first to randomize the order and insure a fair game
O(n)
1 | function shuffle(array){ |
测试shuff如果5x2一共10个格,雷5个,则出现的概率应该都是0.51
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23function testshuff (N,n,m,num){
var freq = Array();
for(var i=0;i<m*n;i++)
freq[i]=0;
var arr = Array()
for(var test=0;test<N;test++){
for(var i = 0;i<num;i++){
arr[i]=1;
}
for(var i = num;i<m*n;i++)
{
arr[i]=0;
}
shuffle(arr)
//console.log(arr)
for(var j=0;j<n*m;j++){
freq[j]+=arr[j];
}
}
for(var i =0;i<n*m;i++){
console.log(i+" "+freq[i]/N);
}
}
假装做个扫雷 生成nxm大小的格子里面有num个雷,并且打乱它1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33function generate(n,m,num){
var mines = new Array()
let x,y;
for(var i =0;i<n;i++){
mines[i]=new Array();
for(var j=0;j<m;j++){
mines[i][j]=0;
}
}
while(num){
x= Math.floor(Math.random()*n);
y= Math.floor(Math.random()*m);
//一定要加,不然雷数少于num
if(mines[x][y]===0){
mines[x][y]=1;
num--;
}
}
return mines;
}
function shuff2d(mines,n,m){
var t,ix,iy,ranx,rany;
for(var i = n*m-1;i>=0;i--){
ix = Math.floor(i/m);
iy = i%m;
var random = Math.floor(Math.random()*(i+1));
ranx = Math.floor(random/m);
rany = random%m;
t = mines[ix][iy];
mines[ix][iy]=mines[ranx][rany];
mines[ranx][rany]=t;
}
}
其他要设置用户点击open[][],这个点周围有多少雷cnt[][],用户插旗坐标flag[][]
另外 点开不是数字的地方要扩展
window.getSelections()
https://developer.mozilla.org/zh-CN/docs/Web/API/Window/getSelection
css 伪类选择器的not
css权重计算?
1 | <head> |
写一个base62.js
requirejs异步加载文件
加载机制:使用head.appendChild()
将每个依赖变成<script>
标签
helper不是xhr是以js形式加载的Content-Type:application/javascript;charset=UTF-8
所以模块加载可以跨域,可以从cdn1
<script data-main = "/js/app" src = "/js/require.js"></script>
app.js1
2
3
4
5
6
7
8
9//不用data-main直接配置base-Url
//在html里两个script标签,先require.js再app.js
requirejs.config({
baseUrl:'/js'
});
require(['helper'],function(helper){
var str = helper.trim(' amd ')
console.log(str)
});
helper.js1
2
3
4
5
6
7
8//模块名,依赖的模块,加载的依赖中的对象(jquery)
define("helper",['jquery'],fucntion($){
return {
trim: function(str){
return $.trim(str)
}
}
});
获取用户信息
1.定义简单对象user.js1
2
3
4
5
6define({
username:'username',
name:'zhou',
email:'abc@abc.com',
gender:'男'
})
2.app.js1
2
3
4
5
6
7
8require(['jquery','../js/api'],function($,api){
$("#user").click(function(){
//.then异步处理
api.getUser().then(function(user){
console.log(user);
})
})
});
3.api.js1
2
3
4
5
6
7
8define(['jquery'],function($){
//异步处理
var def = $.Deferred();
require(['../js/user'],function(user){
def.resolve(user);
});
return def;
});
不支持AMD(require,define)的库:Mondernizr,bootstrap
nodejs 单线程
IO密集:静态资源(文件),网络,数据库
Event loop主进程是单线程,I/O等操作系统多线程调用。
nojs有cluster模块可以在每个核启一个进程不会浪费cpu
移动端自适应
1.css像素即逻辑像素。
一般屏幕【设备像素比】1:1,一个逻辑像素对应一格设备物理像素
Retina屏幕,1:2,一个逻辑像素需要4个物理像素表示
2.viewport分三类
layout viewport 整个网页
visual viewport 在手机上拖动显示的网页的一部分
ideal viewport 手机的宽和高content="width=device-width"
让layout==手机的ideal 手机自动铺满
3.rem:em是相对于父级元素计算大小,rem相对于root element
用viewport和设备像素比可以调整基准像素
spa的好处
不用每次请求消耗dns tcp等接口相应时间。单页面只有接口耗费的时间。
Prerender可以优化SEO
实现
1.History api
pushState
onpopstate
2.Hash
hashchange
location.hash
gulp不用io流式处理 比grunt晚出现
chrome 技巧
截图:ctrl+shift+P Captrue full size screenshot
Web Component 用法
Webview loadUrl
浏览器由7部分组成
用户界面
网络:请求静态资源发起请求
js引擎
渲染引擎:DOM和CSS内容排版 WebKit中Html和CSS解析可以并行
UI后端:选择框、按钮、输入框
js解释器
持久化数据存储
查看渲染计算后的CSS规则
document.defaultView.getComputedStype(document.getElementById("id",null))
css计算权重:!important>内联样式>id选择器>类选择器>元素选择器
nodejs跨域测试
- 被请求的添加
html里
type:xhr1
2
3
4
5<script>
var xhr = new XMLHttpRequest()
xhr.open('GET','http://127.0.0.1:8897')
xhr.send()
<script>
8897:任何服务都能访问这个服务1
response.writeHead(200,{'Access-Control-Allow-Origin':'*'})
或者特定域名1
2response.writeHead(200,
{'Access-Control-Allow-Origin':'http://localhost:8898'})
- jsonp标签里允许跨域不用添加allow-origin
type:script1
<script src="http://127.0.0.1:8897"><script>
CORS预请求 option
跨域只允许get/head/post
content-type只允许 form表单三种数据类型text/plain
multipart/form-data
application/x-www.form-urlencoded
html:报错not allowed by Access-Control-Allow-Headers
1
2
3
4
5
6fetch('http://localhost:8897/',{
method:'POST',
headers:{
'X-cors':'123'
}
})
fetch允许跨域的header
允许的header 其它的都需要服务器端验证先发送option类型再发送post1
2
3response.writeHead(200,{
'Access-Control-Allow-Header':'X-Test-Cors'
})
同理可以添加Allow-Methods
等
设置允许跨域的最长时间不需要再发送option预请求'Access-Control-Max-Age':'1000'
缓存Cache-Control
- 可缓存性
public:http经过的代理服务器、客户端都能缓存
private:只有发起请求的浏览器可以缓存(百度设置了privae) - 过期
max-age:客户端过期时间
s-maxage=代理服务器的过期时间
max-stale=使用过期缓存 - 重新验证
must-revalidate - 其它对代理服务器nginx
no-cache 可以本地缓存。向服务器发起验证是否可以使用本地缓存
no-store 不能本地缓存。
no-transform 不压缩
在请求服务器设置1
2
3response.writeHead(200,{
'Cache-Control':'max-age=200,public'
})
服务端1
2
3
4
5
6
7
8const etag = request.headers['if-none-match']
if(etag === '777'){
response.writeHead(304,{
'Content-Type':'text/javascript',
'Etag':'777'
})
response.end('并不会显示,浏览器直接读了缓存')
}
设置Cookie
禁止javascript修改cookie1
2
3
4response.writeHead(200,{
'Set-Cookie:['id=123;max-age=2','abc=456;HttpOnly']
})
response.end(html)
'adc=456;domain=test.com'
不能跨域设置给a.test.com
长链接Network-Connection ID(TCP链接的id)
http1.1发送请求有先后顺序。不能并发请求
chrome允许并发限制创建6个
保持长链接Connect:Keep-Alive
默认都是keep-alive
本地开发 把网速调慢:online->Fast 3G
可以设置'Connection':'close'
google 使用h2 都是一个connectID
数据协商
Accept
Accept-Encoding
Accept-Language
mimetype
'X-Content-Type-Options':'nosniff'
禁止浏览器自动猜测返回类型
使用gzip压缩1
2
3
4
5
6
7const fs = require('fs')
const zlib = require('zlib')
const html = fs.readFileSync('test.html')
response.writeHead(200,{
'Content-Encoding':'gzip',
})
response.end(zlib.gzipSync(html))
表单如果用ajax使用application/json或者application/xml1
2
3
4
5
6<form action ='/from' id = "form" method = "POST" enctype="multipart/form-data">
<input type = "text" name = "name">
<input type = "password" name = "password">
<input type="file" name="file">
<input type ="submit" name = "submit">
</form>
ajax发送1
2
3
4
5
6
7
8
9var form = document.getElementById("form")
form.addEventListener('submit',fumction(e){
e.preventDefault()//页面不会跳转
var formData = new FormData(form)
fetch('/form',{
method:'post',
body:formData
})
})
会自动带上Content-Type
redirect
只有302的头才表示跳转1
2
3response.writeHead(302,{
'Location':'/new'
})
改成301永久变更 浏览器会自动只发送/new的请求 /new的路由放到了缓存里。接下来改成200也读不到了。
CSP content-security-policy 内容安全策略
1 | 'Content-Security-Policy':'default-src http:https' |
考虑同一域名的浏览器请求上限将html放在admin.domain.com下,js+css放在s.下,将image放在image.下
前端访问后端api.发生跨域需要使用代理服务器
304是协商缓存 还会和服务器通信一次
本地缓存(cache-control/expires) 通过html中引用css地址更新v1放弃缓存 用摘要算法当文件更新时更新css文件名
静态资源部署在cdn,动态网页部署在另一个节点。
1 先更新页面:加载旧缓存,页面样式错乱
2 先静态资源后页面:有缓存则不更新,第一次访问的没缓存用户 页面执行错误。
访问量小的网站可以先静态资源后页面
非覆盖式发布:新旧css同时存在cdn上,再更新html页面
全局微软雅黑document.getElementByTagName("body").sytle.fontFamily="微软雅黑"
Array.from(document.getElementByTagName("p").forEach((item)=>item.style.fontFamily="微软雅黑"))
- import有无default ,default导出的只能一个,所以不用大括号
webpack-dev-server 开发模式
wepack.config.js:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15const isDev = process.env.NODE_ENV==='development'
const config={
target: 'web'
}
if(isDev){
config.devSever ={
port:8888
host:0.0.0.0,//可以在内网中用内网ip用手机访问测试
overlay:{
errors:true,
},
historyFallback:"index.html",
hot:ture//只渲染当前组件
}
}
安装corss-env在windows平台下设置NODE_ENV要用set和linux不同
package.json1
2
3
4"script":{
"build":"cross-env NODE_ENV=production webpack --config webpack.config.js",
"dev": "cross-env NODE_ENV=development webpack-dev-server --mode development --config webpack.config.js"
}
html-webpack-plugin
autoprefixer
postcss.config.js
优化css代码 自动加webkit等前缀
mixin模式
typeof一共有五种返回值
按存储方式只有值类型和引用类型(共用内存块)
只能区分值类型。无法区分引用类型:数组、对象、方法
强制类型转换
==
1 | 100=='100'//true |
if和逻辑运算符
判断变量被当成true还是false1
2var a = 100
console.log(!!a)//true
何时使用===和==
除了1
2
3
4obj.a==null
//相当于
obj.a===null||obj.a===undefined
//来自jquery
其它都用===
12个js内置函数 (数据封装类对象)
JSON和Math也是内置对象1
2JSON.stringify({a:10,b:20})
JSON.parse('{"a":10,"b":20}')
原型
js构造函数
1 | //构造函数 |
Class语法
1 | class MathHandle{ |
语法糖实现
MathHandle===MathHandle.prototype.constructor
true
继承
1 | function Animal(){ |
window.onload和DOMContentLoaded区别
zepto
rollup.js 比webpack小
babel src/index.js
zepto小型jquery专门移动端开发
Rivets.js数据绑定
js
预处理器 pug webpack 模版处理器(jade)
数组
arr.includes(4)
true/false.find
1
2
3let result = arr3.find(function (item,index) {
return item.toString().indexOf(5)>-1
}).some
找到true后停止返回true.every
找到false后停止返回false.reduce
变成undefined是因为没有写返回值
- 对象求和:
1
2//不报错,返回NaN 因为pre从对象变成了数
[{price:30,count:2},{price:20,count:3},{price:40,count:4}].reduce((prev,next)=>prev.price*prev.count+next.price*next.count)
正确写法:1
2
3[0,{price:30,count:2},{price:20,count:3},{price:40,count:4}].reduce((prev,next)=>prev+next.price*next.count)
//或者添加默认参数
[{price:30,count:2},{price:20,count:3},{price:40,count:4}].reduce((prev,next)=>prev+next.price*next.count,0)
- 数组扁平化:二维数组变成一维
1
[[1,2,3],[4,5,6],[4,5,6]].reduce((prev,next)=>prev.concat(next))
箭头函数
let a = b => c => b+c
a(1)(2)=3(return function(c){b+c})
闭包:返回的是引用数据类型,赋值给外界变量,不会被销毁。
更改this指向
call和apply和bind
apply\call详解
绑定this上下文,call和apply使函数立即执行
bind返回函数
自己实现bind1
2
3
4
5
6
7
8
9
10if (!Function.prototype.bind) {
Function.prototype.bind = function () {
var self = this, // 保存原函数
context = [].shift.call(arguments), // 保存需要绑定的this上下文
args = [].slice.call(arguments); // 剩余的参数转为数组
return function () { // 返回一个新函数
self.apply(context,[].concat.call(args, [].slice.call(arguments)));
}
}
}
文档碎片
在赋值操作中
A||B
:A真返回A,A假返回BA&&B
:A假返回A,A真返回B &&优先于||
应用场景:1
2
3
4function fn(num,callBack){
num=num||0//undefined会转换成false
callBack&&callBack();//只要传了函数进来callBack为真
}
闭包
里边的作用域被赋值给外面的变量占用了,不能释放。1
2
3
4
5
6
7
8
9
10
11var a = 9;
function fn(){
a=0;
return function(b){
return b+a++;
}
}
var f=fn()//占用 function(b)
console.log(f(5))//输出5.f(5)执行后会销毁 全局a=1
console.log(f()(5))//修改全局a=0 输出5 执行完后a++ 全局a=1
console.log(f(5))//输出6 从fn到return之间的被保留
类数组 (arguments形参集合)
- 以0~n数字作索引
- length
- arguments.callee是函数本身 严格模式不使用
- arguments.caller 是fn 严格模式不使用
- Array.from()将类数组转换成数组
1
2function sum(){console.log(arguments.callee.caller)}
function fn(){sum(1,2,3,4)}
立即执行函数IIFE
function t (num){console.log(num)}(3)
- 浏览器的【全局作用域】是window,nodejs的全局作用域是global
var a=1 给window加了属性 - 对象数据类型:
- 浏览器开辟内存空间分配一个16进制的地址,
- 内存空间存对象键值对
- 给对象变量存地址
任意数求和1
2
3
4
5
6function fn(){
//类数组转化成数组
var ary = Array.prototype.slice.call(arguments);
return eval(ary.join('+'))
}
fn(12,23,34)
- 函数与对象的创建相同也是地址,函数把js代码当作字符串存到空间中
- js中栈内存是作用域,用于执行代码,存放基本数据类型。堆内存用于存储键值对or函数字符串
调用栈是连续空间。后进先释放,要节约栈空间。堆是链表。 - 变量提升:在当前作用域,浏览器把所有
- 带var的声明,
- 带function的声明并定义(defined赋值(代码字符串的地址))
- 全局作用域var相当于给window加了属性
单例模式:团队合作防止全局变量污染:封装到对象
内置类
htmlCollection元素集合类
1
2
3getElementByTagName
getElementByClassName
querySelectorAllNodeList 节点集合类
1
2getElementByTagName
childNodesproto:HTML[Div]Element元素对象->HTMLElement->ELement->Node->EventTarget->Object
构造函数
构造函数执行方式new
fn() 普通函数 fn()
this是window
1
2
3function fn(num){
console.log(this)
}调用构造函数时 this指向函数本身 输出:nfn的属性nnn:10
构造函数过程:创建this实例,对this赋值并返回this
并且每次new都是不同实例1
2
3
4
5function nfn(nnn){
console.log(this)
this.nnn=nnn;
}
var ff = new nfn(10)
判断JS数据类型的4种方法
- typeof 无法区分正则和array 都返回object
- instanceof 检测当前实例是否属于这个类
- .constructor(对象实例的constructor是类)
- Object.prototype.toString.call
in/hasOwnProperty
hsOwnProperty是通过原型链检测是否是Constuctor的实例
区别:Object.hasOwnProperty('hasOwnProperty')
false'hasOwnProperty' in Object
true
hasOwnProperty用于检测私有属性
in 私有共有都返回true
共有:类提供,所有实例都能用 (静态方法)
原型和原型链
类是函数,实例是对象。
- 函数的
prototype
属性是对象 - 实例的
__proto__
属性是对象 typeof Object
“function” 所有的类都是函数类型Function instanceof Object
->true- 所有内置类String/Number 也是”function”类型
原型 三个自带的属性
原型链:实例的__proto__
是类的prototype
prototype对象(原型对象)是所有
函数
的属性。
存储了当前类给实例提供的公共属性和方法
通过prototype定义类:使用new Person获得实例1
2
3
4
5
6
7var Person = function(){};//function Person(){}
Person.prototype = {
name : 'ecmadao',
sayName : function(){
console.log(this.name);
}
};prototype对象,带
constructor
属性存的值就是函数本身(类)- 每个对象都带
__proto__
属性,值是当前对象所属类的原型(prototype)1
2
3
4function fun(num){
this.num = num}
var f1 = new fun(10)
fun.prototype=== f1.__proto__ //true
对fun.prototype添加的方法1
fun.prototype.say = function(){console.log("prototypesay")}
对f1来说f1.hasOwnProperty('say')
false . 是公共方法
fun.prototype.__proto__
是Object.prototypeObject.prototype
没有__proto__
有也指向自己
构造原型
Fn.prototype = {}
- 会没有constructor,使用
constructor:Fn
- 会导致原来使用
Fn.prototype.c=function
的属性被替换(可以遍历原有的克隆) 1
2var jQuery = function(selector,context){return new jQuery.fn.init(,)}
jQuery.fn = jQuery.prototype={constructor:jQuery,init:function(,){}}
BOM
document.querySelector("body").setAttribute("style","background-color:black");
document.querySelector("body").style.cssText="background-color:black";
https://chromium.googlesource.com/chromium/src/+/master/docs/es6_chromium.md
前端模块化 CommonJS
CommonJS是不适用于浏览器端,因为文件是从服务器请求过来,不能同步加载模块。
浏览器模块化AMD规范:require.js
非同步,指定回调函数
浏览器中异步加载。可以并行加载多个模块。
???如何并行?CMD规范:按需加载sea.js
ES6模块化
- 通过babel将不被支持的import编译为当前受到广泛支持的 require
加载过程
defer 与相比普通 script,有两点区别:载入 JavaScript 文件时不阻塞 HTML 的解析,执行阶段被放到 HTML 标签解析完成之后
虚拟DOM
https://segmentfault.com/a/1190000015821780
- Virtual Node
- 用json构建,type\props\children
{type:”div”,props:{“style:”},children:[]}
vnodes->vdom
柯里化currying:函数式编程风格,组合函数
1 | //两数相乘 |
Object.defineProperty 为对象定义属性
- js对象or DOM对象
- 属性名
描述符:
{value: “covergou”, writable: false, enumerable: true, configurable: false}
1
2let obj ={}
Object.defineProperty(obj,"school",{get:,set:})- value:”name”
writable:true/false
是否可写configurable:false
删除属性、修改属性(writable, configurable, enumerable)的行为将被无效化enumerable: true
是否能在for-in循环中遍历出来或在Object.keys中列举出来get/set:function(){}
使用get/set不能有writable和value属性
实现数据双向绑定
数据劫持1
2
3
4
5
6
7
8Object.defineProperty(dom, 'translateX', {
set: function(value) {
var transformText = 'translateX(' + value + 'px)';
dom.style.webkitTransform = transformText;
dom.style.transform = transformText;
}
})
dom.scale = 1.5;
ES6
对象拷贝
Object.assign({t:1},{k:2})
默认参数
1 | function hello(txt){ |
es6:1
function(txt = 'hello world'){}
模板字符串
1 | var name = 'moe' |
箭头函数
import
- {}块状作用域
- .map(function(v){return v+1})
.map(v=>v+1) - 箭头函数内的this指向是定义时this的指向
function中this指向是该函数被调用的对象
数组
类方法:
Array.form(1,2,3,4)
转成数组.from(3)
生成空位Array.of(3)
与from用法相同,解决了单个值数组toArray(1,2,3,4)
转数组
原型方法(用于实例)
.copyWithin(target,start,end)
- cool()函数丢失了同this之间的绑定
var self = this
1 | var obj = { |
- setTimeout中的this指向的是全局对象
- var self = this
- function(){}.bind(this),1000
显示所有全局变量
1 | for(name in this){ |
对象保护 对象代理
ES3,ES5
1
2
3
4
5
6
7
8
9//声明类
var Person= fuction(){
var data={
name='es3',
sex:'male',
age:15
}
this.get,this.set = function(){}
}es5:对象的只读属性
Object.defineProperty("Person",'sex',{ writable:false,value:'male' })
只能读不能写- ES6用代理访问对象
1
2
3
4
5
6
7let Person={:,:,:}
let person = new Proxy(Person,{
get(target,key){
target[key]
},
set(target,key,value)
})