way 2 explore

坚持学习


  • 首页

  • 归档

vue2.X数据绑定原理

发表于 2018-10-17

vue2.0数据绑定原理

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
33
34
35
36
37
38
39
40
41
42
let data = { price: 5, quantity: 2 }
let target = null
class Dep {
constructor () {
this.subscribers = []
}
//记录target
depend () {
if (target && !this.subscribers.includes(target)) {
this.subscribers.push(target)
}
}
//调用每一个target
notify () {
this.subscribers.forEach(sub => sub())
}
}
Object.keys(data).forEach(key => {
let internalValue = data[key]
//为该属性添加依赖类
const dep = new Dep()

Object.defineProperty(data, key, {
get() {
dep.depend()
return internalValue
},
set(newVal) {
internalValue = newVal
dep.notify()
}
})
})
function watcher(myFun) {
//全局属性target
target = myFun
target()
target = null
}
watcher(() => {
data.total = data.price * data.quantity
})
1
2
3
4
5
data.total
10
data.price = 20
data.total
40

步骤解析:

  1. 调用target,执行data.total = data.price * data.quantity,触发data.price的getter,执行dep.depand(),将target记录下来,data.quantity同理
  2. data.price = 20触发data.price的setter,执行dep.notify(),将subscribers中记录的每一个target执行一次。

参考

node.js学习笔记

发表于 2018-10-15

process

传参相关

  1. process.argv

    1
    2
    3
    4
    5
    6
    [ 
    'C:\\Program Files\\nodejs\\node.exe',//node安装目录
    'C:\\pro\\mutipage-proj\\build\\dev.js',//当前执行js的路径
    'a=b',//通过package.json中的script传参,比如node build/dev.js a=b
    'proj=csr' //通过npm命令传参,比如npm run dev proj=csr
    ]
  2. process.env.npm_config_argv

服务器端渲染与客户端渲染

发表于 2018-10-15

server side render
client side render

my git way

发表于 2018-10-15
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
//新建分支并切换
git checkout -b weixy
//等价于
git branch weixy
git checkout weixy
//撤销修改,红字变无。注意:文件夹路径有空格的情况
git checkout 文件

//撤销add,绿字变红字
//全部
git reset .
//某个
git reset 文件

//撤销commit
//修改commit备注
git commit --amend
//合并分支
//方式1.merge
//方式2.rebase

//情景:在dev分支下开发新需求,临时线上出现bug,需要切换到master分支下改,但此时dev分支下的修改还不能提交
//解决办法:git stash 暂存修改
//完成后,再将修改pop出来。git stash pop

web安全

发表于 2018-09-28

web安全

cookie泄露的途径

cookie读取:document.cookie

如何发请求:

  1. xss,嵌入脚本如script、img、iframe等等,不受同源策略限制

ES6之class

发表于 2018-09-28

ES6之class

ES6中class+extends实现继承与ES5实现继承的区别

es5继承
es6继承

一、私有属性和私有方法的实现

  • ES5

  • ES6变通的方式模拟实现

  1. 命名上使用_

    1
    2
    3
    4
    5
    6
    7
    8
    class Foo{
    publicMethod(){
    console.log('i am public method');
    }
    _privateMethod(){
    console.log('i am private method');
    }
    }
  2. 定义在外部

    1
    2
    3
    4
    5
    6
    class Foo{
    bar(){
    baz.call(this);
    }
    }
    function baz(){}
  3. symbol唯一性
    待开拓…

  • 新提案

    #表示

    1
    2
    3
    4
    5
    6
    class Foo{
    #prop = 'i am 私有属性';
    #method(){
    console.log('i am 私有方法');
    }
    }

二、静态属性和静态方法的实现

  • ES5

    1
    2
    3
    4
    5
    6
    7
    function Person(){

    }
    Person.blood = "red";
    Person.getEyes = function(){
    return 2;
    }
  • ES6,class内部只有静态方法,没有静态属性

    1
    2
    3
    4
    5
    6
    class Foo{
    static classMethod(){
    console.log('i am 静态方法');
    }
    }
    Foo.prop = 'i am 静态属性';
  • 新提案

    1
    2
    3
    class Foo{
    static prop = 1
    }

同源策略及解决方案

发表于 2018-09-25 | 更新于 2018-09-28

什么是同源策略

出处

浏览器的同源策略,服务器端是没有同源策略的

  • script标签的src
  • img的src
  • iframe的src
  • link的href

是不受同源策略限制的

存在的合理性

浏览器的同源策略出于对cooKie安全性的考虑

不存在的话存在什么样的问题

源是什么,怎么样就算跨域,跟谁比较

源:
window.location.origin = protocol+host+port
origin不一样

解决方案

情况一:跨域调用接口请求数据

1.jsonp

原理:script标签不受同源策略限制
缺点:只支持get请求
现成库:Jsonp

2.cors(cross origin resource share跨域资源共享)

实现机制:
浏览器自动实现,不需要前端开发者做额外的工作,跟普通ajax请求一样,只是(后面重点):当浏览器检测到ajax的url跨域时,会自动附加一些请求头(Origin本次请求来自的源),甚至会多发一次请求option。

option请求的作用:查询指定url支持的方法。会返回Allow:get,post,head这样的内容。

所以,实现cors的关键是,服务器。只要服务器实现了cors接口,就能进行跨域通信。

3.代理服务器

原理:服务器不受同源策略的限制
举个栗子:webpack-dev-server配置proxy

情况二:iframe传递数据

1.条件:一级域名相同,二级域名不同。设置document.domain为相同的部分

举个栗子:
www.silvia.com
www.wxy.silvia.com
设置document.domain = “silvia.com”

2.postMessage

测试下

3.利用hash

1
2
3
4
5
6
//父
var ifr = document.getElementById('ifr');
var newSrc = ifr.src + '#lalla';
document.getElementById("btn").addEventListener('click',function(e){
ifr.src = newSrc;
})
1
2
3
4
//在父获取iframe的window:
document.querySelector('iframe').contentWindow
//在iframe获取父window:
window.parent

4.window.name

备忘推送实现

发表于 2018-09-23

步骤:

  1. 一登录请求 最近一条备忘
  2. 建立定时任务
    setTimeout(function(){
     //回调做的事:
     1. 判断当前会话是否超时
     2. 未超时就弹备忘
     3. 弹备忘后,请求 备忘确认接口,后台返回 最近一条备忘,setTimeout
    },后台返回的时间间隔)
    

注意:
如果期间有 备忘的增删改查,前端会根据后台的返回,替换定时任务。
登出操作(包括用户主动注销和会话超时)时,清除定时任务。

继承

发表于 2018-09-23

目标:实现sub函数继承super函数

原型链

1
2
//关键代码
sub.prototype = new super();

缺点:

  1. 无法在不影响sub所有对象实例的情况下,给super的构造函数传参
  2. 引用类型值的super原型属性会被所有sub实例共享

调用构造函数,改this

1
2
3
function sub(){
super.call(this,参数)
}

要点:相当于把super构造函数复制到sub构造函数中执行
新创建的sub对象上执行super函数中的所有对象初始化代码,所以!sub的每个实例都会有自己的属性(和super一样的属性)副本了。

缺点:

  1. 只能继承super的成员方法,无法继承super原型

组合继承

1
2
3
4
5
6
7
8
function sub(){
super.call(this,参数)
}
sub.prototype = new super();
//sub原型的consructor 属性指向自己
sub.prototype.consructor = sub;
//新增公用方法
sub.prototype.getName = function(){}

性能优化(未完待续)

发表于 2018-09-23 | 更新于 2018-10-15

1. http请求数量

合并。举个栗子:css精灵图

2. http请求大小

压缩。
举个例子:webpack插件UglifyJsPlugin、

1
2
3
4
5
6
optimization:{
minimizer:{
new UglifyJsPlugin({...}),
new
}
}

3. css方面

  • 减少回流reflow(reflow与repaint的区别)
    方式:
    1. 减少布局方式的样式修改。举个栗子:隐藏显示
    2. 通过把样式放到class中,一次性更改样式
    

4. dom操作上

  • 插入createDocumentFrament()。在dom添加新节点的时候,先存在文档片段中,再一次性添加到DOM中。
  • 使用innerHTML而不是appendChild
  • 缓存elementCollection,文档查询代价高
  • vnode思想

5. 其他资源,如图片资源

  • css精灵图
  • 懒加载、预加载

6. 事件

事件代理,利用事件冒泡,为顶层元素绑定事件处理程序,就可以处理所有子元素的事件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
//跨浏览器实现
//获取事件对象
ev= ev || window.event;
//禁止传播,冒泡/捕获
if(ev.stopPropogation){
ev.stopPropogation();
}else{
ev.cancleBubble = true;
}
//阻止默认行为
if(ev.preventDefalut){
ev.preventDefault();
}else{
ev.returnValue = false;
}

7. js语法

  • 多个if-else使用switch-case替代,按照最可能到最不可能排序;
  • 优化循环
    1. 循环条件与0比较,存储长度值;
    2. 如果循环至少执行一次,可以考虑后循环测试即do-while,可以避免第一次的循环条件测试;
    3. 如果循环次数确定,可以考虑展开循环体,避免了创建循环和条件测试的开销;
    4. 如果循环次数较大,可以考虑duff装置(减少迭代次数,一次迭代运行多次当个循环体);
    5. 条件(不在乎顺序,且循环次数确定)满足的情况下,选择减值迭代:
      展开循环(循环次数已知且较少)参考

      DUff装置(循环次数不能确定,数据量大)核心:将“零头”与“整数”分成两个单独的do-while循环

  • 多个变量声明只使用一次var关键字(语句数量会影响效率,尽量合并语句)

单页应用首屏优化

  • 路由懒加载,使用动态import语法
    使用命名chunk可以 实现某个路由下所有组件打包到用一个异步块中。特殊的注释语法来提供chunkname
  • 缓存:chunkhash和hash的区别
  • 代码分割
    css分割,ExtractTextPlugin
  • cdn:
    第三方插件
    图片资源

芝士点补充:

  • 浏览器重绘网页的频率是60FPS(即16毫秒/帧),JavaScript做不到在16毫秒内完成DOM操作,因此产生了跳帧。用户体验上的不流畅、不连贯就源于此。
12
silviawxy

silviawxy

12 日志
7 标签
© 2018 silviawxy
由 Hexo 强力驱动 v3.7.1
|
主题 – NexT.Pisces v6.4.1