goldeli / blog Goto Github PK
View Code? Open in Web Editor NEWBlog
License: MIT License
Blog
License: MIT License
this
指向(window
或者 globe
)this
指向改对象new
,this
指向新的实例var video = {
name: "coco",
tags: [1,2,3],
play: function() {
this.tags.forEach(function(tag) {
console.log(this.name, tag)
})
},
country: {
name: "china",
print: function() {
console.log(this.name)
}
}
}
video.play()
// window 1
// window 2
// window 3
video.country.print()
// china
this
指向 window
,是因为 forEach
方法传入的就是一个普通函数。this.tags
指向调用它的对象。print
方法中的 this
也是指向调用它最近的对象。基本类型:Null
Undefined
String
Number
Boolean
Symbol
引用类型:Object
Function
判断类型的方法:type of
判断实例与构造函数依赖的方法:instanceof
在 JavaScript 中万物皆对象。Null 是所有对象的源头,Null就像上帝,Function 和 Object 就是亚当和夏娃,它们通过 prototype 和 constructor 繁衍后代,prototype 提供基因,constructor 就是子宫。
__proto__
属性。__proto__
都指向它的构造函数的 prototype 属性。用代码来描述:
// 对象可扩展
var obj = {};
obj.b = 1
var arr = [];
arr.b = 1
function fn() {}
fn.b = 1
// 判断对象中是否存在该属性
obj.hasOwnProperty('b') === true
// __proto__
console.log(obj.__proto__)
console.log(arr.__proto__)
console.log(fn.__proto__)
// 只有函数有 prototype
console.log(obj.prototype) // undefined
console.log(arr.prototype) // undefined
console.log(fn.prototype)
// 应用类型的 __proto__ 属性指向它构造函数的 prototype 属性
console.log(fn.__proto__ === fn.constructor.prototype)
console.log(fn.__proto__ === Function.prototype)
console.log(arr.__proto__ === Array.prototype)
console.log(obj.__proto__ === Object.prototype)
当对象 obj
在访问属性的时候,会在自身属性中寻找,如果自身没有,就会通过 obj.__proto__
(即构造函数的 prototype
)中去寻找。如果还没有就会继续通过 obj.__proto__.__proto__
中去寻找,一直向上寻找,就形成了原型链。如果在最上层也没找到,就会返回 undefined
。
最上层是什么 —— Object.prototype.__proto__ === null
作用域的目的是确定变量的访问权限,也就是为了避免变量污染。
首先 JavaScript 采用的是词法作用域,也就是静态作用域,即创建的时候就确定好了。
在ES6以前,JavaScript 只有全局作用域和函数作用域,没有块级作用域,不像 Java 那样,一个花括号就是一个作用域。
在ES6中 引入了 let 关键字,才有了块级作用域。
当变量查找时,会从当前上下文中的变量对象中查找,如果没有,会从父级上下文的变量对象中查找,直到找到全局的变量。由多个执行上下文的变量对象构成的链表就叫作用域链
console.log(a) // undefined
var a = 1
console.log(b) // 报错
b = 2
当一段 JavaScript 执行时,要先经历一个解析阶段,就是把要用的变量放入全局的执行上下文,比如解析到 var a
时,会将 a 扔到全局执行上下文中。
开始执行代码,当用到 a 变量时,a 还未被赋值,被得到 undefined。
b 未使用 var 关键字来定义,所以不会放到全局执行上下文中,当用到 b 时,会报错,b 未定义。
函数也有执行上下文,比全局执行上下文多 this
arguments
闭包指的是,有权限访问访问其他作用域中变量的函数。
理解闭包核心:JavaScript的函数作用域是在函数创建的时候定义的,而不是在执行的时候创建的
看下面的例子:
function out() {
var name = "js"
return function inner(){
console.log(name)
}
}
var fn = out() // fn 引用了 out 的作用域
fn() // 当 fn 执行的时候就可以访问到 out 的作用域中的 name 变量
引用计数
当声明一个变量,将一个引用类型赋值给该变量,则当前引用次数为1,如果同一个值赋给另一个变量,则引用次数加1。相反,如果拥有该值的变量拥有了其他值则减1,当值的引用次数为0时,垃圾回收期下次运行时,就会回收。
下面这个例子:
function func() {
var a = new Object()
var b = new Object()
a.someOtherObject = b
b.otherObject = a
}
// 这两个值引用次数都为2,永远不会回收
标记清除
当函数中声明一个变量,则标记这个变量为“进入环境”,只要进入相应的环境你就可以访问到它。当变量离开环境时,则将其标记会“离开环境”
JavaScript 实现异步的方法?
由于回调函数的写法会导致,函数嵌套,造成代码横向发展,而不是纵向发展,从而难看难维护。
Promise 应运而生。
基本用法:
function func(resolve, reject){
setTimeout(function(){
resolve('func')
},500)
}
new Promise(func)
.then(function(data){
console.log(data)
return 'next'
})
.then(function(data){
console.log(data)
})
Promise 解决了代码横向发展的问题,但一眼望去全是 .then,可读性很差。
所以又出现了 generator 来解决这个问题:
generator 基础应用:
var fetch = require('node-fetch');
function* gen(){
var url = 'https://api.github.com/users/github';
var result = yield fetch(url);
console.log(result.bio);
}
var g = gen();
var result = g.next();
result.value.then(function(data){
return data.json();
}).then(function(data){
g.next(data);
});
generator 是 ES6 对协程的实现,yield 可以暂停函数。generator 需要手动通过 .next() 来启动函数继续执行,加上 * 和 yield 让人很难理解。
async/await 目前来说终极的解决方案:
基本用法:
function timeout(ms) {
return new Promise((resolve) => {
setTimeout(resolve, ms);
});
}
async function asyncPrint(value, ms) {
await timeout(ms);
console.log(value)
}
// 5秒后打印 hello world
asyncPrint('hello world', 5000)
async/await 其实就是 generator 的语法糖,* 号相当于 async,yield 相当于 await。await 有了返回值后会继续执行不需要像 generator 需要通过 .next 来启动函数继续执行
作用域的目的是确定变量的访问权限,也就是为了避免变量污染。
首先 JavaScript 采用的是词法作用域,也就是静态作用域,即创建的时候就确定好了。
在ES6以前,JavaScript 只有全局作用域和函数作用域,没有块级作用域,不像 Java 那样,一个花括号就是一个作用域。
在ES6中 引入了 let 关键字,才有了块级作用域。
React is one of the most popular javascript libraries and it's going to be more popular in 2019 and beyond. React is released in 2013 and it gained a lot of popularity over the years. It's a declarative, component-based and efficient javascript library for building user interfaces.
计算机程序通常是由数据结构+算法
组成的。
知识点总览:
数据结构决定了空间和时间的处理效率,根据不同的场景确定不同的数据结构。
读的多的数据,要想竟可能想办法提高读取效率,比如IP 的数据储存,他可能只会写一次,而读取很多次。
有序数据结构比如数组存储,节省空间,但查找慢。用无序数据结构比如对象存储,用 key
就可以快速查找到。
对于简单的数据结构,在 ES 中对应的是 Array 和 Object。可以想象下数组是有序的而对象是无序的,对象可以通过 key快速获取值,而数组则有个查找过程。
算法分为时间复杂度和空间复杂度。
时间复杂度指的是算法运行的时间,空间复杂度指的是算法运行所需的储存空间。
一般遵循这几个原则:
O(n)
,两重循环 O(n^2)
,一次类推。O(log(n))
。举个例子:
var i = 0; // 这条语句执行1次
while(i < n) { // 这条语句执行n次
console.log(i); // 这条语句执行n次
++i; // 这条语句执行n次
}
算法复杂度计算:1 + n + n + n = 1 + 3n,去除常数项,复杂度为 O(n)
问题:
style=""
权重为1000#box
权重为100.box
:hover
[attribute]
权重为10p
div
权重为1权重值越大优先级越高,相同权重遵循后定义的覆盖先定义的
三个核心:padding
、border
、margin
盒子的宽度:内容宽度 + padding
宽度 + border
宽度 + margin
宽度。改变任何一个都会改变整个宽度。
如果设置了box-sizing:border-box
,那么设置 width:100px
时,这100px
包含了(内容 + padding
宽度 + border
宽度)
当两个 div
的 margin
为 20px,那么两个div的纵向的距离不是 40px,而是20px,因为纵向的 margin
会重叠。如果一个的比另一个的 margin 大,那么遵循大的吃小的原则。
float 的设计初衷是为了图片的环绕效果,当图片设置了 float:left
文字会环绕图片周围。
人们发现 float + div 可以解决类似 table 的布局,所以 float 现在常常用来布局。
破坏性
如果子 div 设置了 float,会导致父 div 出现坍塌。因为设置 float 会让子 div 脱离文档流
包裹性
div 属于块级元素,如果不设置宽度,会撑满整个宽度,当设置 float:left
时,会让 div 包裹文字。这就印证了它的设计初衷,让文字环绕图片,如果没有包裹性,它就无法紧贴文字。
清空空格
当几个图片在一排显示时,有留有空格。设置 float 让图片脱离文档流,既然都脱离文档流了,那么什么空格换行都跟他没关系了。
清除浮动
浮动会导致脱离文档流,导致布局错乱,所以需要触发 bfc 来清除浮动,清除浮动常见的方式:
.clearfix:after {
content: '';
display: table;
clear: both;
}
.clearfix {
*zoom: 1; /* 兼容 IE 低版本 */
}
BFC 全称 Block Format Context,可以想象成一个盒子,营造一个封闭空间,盒子里面和外面相互不影响。在说 BFC 之前先来看看元素定位问题。
常见的定位方式有三种:
元素按照从上到下,从左到右,以此排列。如果是行内元素,从左到右,铺满换行。如果是块级元素,他会默认占满一行,所以会从上到下排列
float 会脱离普通文档流,元素按照当前的位置,向左或者向右靠。
脱离普通文档流,他的位置不会受到别的元素影响,也不会去影响其他元素。通过绝对坐标来确定位置。
BFC 具有除了普通文档流的其他特性,比如 margin 重叠的问题,如果触发 BFC,margin 就不会重叠。比如 BFC 会 阻止设置 float 导致的文字环绕,所以 BFC 还是清除浮动。
那怎样才能触发 BFC 呢?
比较常用的,overflow:hidden
, overflow 除 visible 的属性外都可以触发
可选属性 static/relative/absolute/fixed
absolute
基本使用:
<style type="text/css">
.container {
display: flex;
}
.item {
border: 1px solid #000;
flex: 1;
}
</style>
<div class="container">
<div class="item">aaa</div>
<div class="item" style="flex: 2">bbb</div>
<div class="item">ccc</div>
<div class="item">ddd</div>
</div>
水平居中
text-aligin: center
.container {
text-align: center;
}
.item {
width: 1000px;
margin: auto;
}
.container {
width: 500px;
height: 100px;
position: relative;
}
.item {
width: 100px;
height: 100px;
position: absolute;
left: 50%;
margin-left: -50px
}
垂直居中
.container {
height: 50px;
line-height: 50px;
}
可以用绝对定位居中(同上),也可以用 margin:auto
,不需要提前知道尺寸,且通用性好。
.container { position: relative; height: 300px; }
.item {
width: 100px;
height: 50px;
position: absolute;
left: 0;
top: 0;
right: 0;
bottom: 0;
margin: auto;
}
让人和机器更容易读懂代码
比如 h1 p header strong 这些标签,方便搜索引擎爬网页
@keyframes testAnimation {
0% {background: red; left:0; top:0;}
25% {background: yellow; left:200px; top:0;}
50% {background: blue; left:200px; top:200px;}
75% {background: green; left:0; top:200px;}
100% {background: red; left:0; top:0;}
}
div {
width: 100px;
height: 50px;
position: absolute;
animation-name: testAnimation;
animation-duration: 5s;
}
重绘:指的是浏览器重新绘制样式,比如颜色,背景等,不会脱离文本流。
回流:当元素的大小,或者属性发生改变,会导致浏览器重新渲染部分或者全部文档
相比之下,回流比重绘更消耗性能。编码时,要尽量避免回流。
思考:如何优化一下代码
for (var i = 0; i < data.length; ++i) {
dom.innerHTML = '<p>'+data[i]+'</p>'
}
当输入 URL 回车之后,会发生加载和渲染两个过程:
为什么 CSS 加载要放到 HTML 的头部?
让浏览器先拿到 CSS 文件,生成 CSSOM,当 DOM 生成后可以一次性生成 RenderTree,避免页面卡顿
为什么 JavaScript 文件要放到 HTML 底部?
由于 JavaScript 执行的线程和页面渲染的线程是同一个,所以遇到 script 标签时,会阻塞渲染。当用户打开页面,应该让用户先看到页面,所以将 JavaScript 文件放到 HTML 底部。
还有一个原因是,如果 JavaScript 中涉及到 DOM 操作,放到 HTML 底部可以确保 DOM 已经渲染完成,并能操作到相关节点。
性能优化大体思路,主要分为两个部分:
比如,当用户输入用户名密码后,数据提交到后端,后端直接拿用户名密码拼接 SQL 语句。如果用户输入恶意的代码,那最后拼接的 SQL 就会有问题,造成 SQL 注入。
解决方式之一,加入用户输入校验。
比如你在某网站上发布一篇文章,在文章中写了一些代码,比如 document.cookie
来获取访问该网页的用户,并将该用户的 cookie 上传到你的服务器。
解决办法:
对敏感的 cookie 这是 http-only
来阻止 JavaScript 脚本的访问。
过滤用户的输入,比如
& 替换为:&
< 替换为:<
> 替换为:>
” 替换为:"
‘ 替换为:'
/ 替换为:/
假如一个支付网站的转账接口是 http://www.bug.com?id=123&money=1000
,请求该接口转账完成。
如果用户登录了 www.bug.com
,此时用户打开了一个邮件,邮件中有这么一行代码 <img src = "http://www.buy.com?id=123%money=1000"></img>
。这样就在用户不知情的情况下偷偷的把1000块钱转给了id为123的账号。
解决方法:
对凡是涉及到支付的接口,都要单独输入密码,或者重新登录。
Introduce some code snippets.
IO
,Timer
Promise
,MutationObserver
Tasks, microtasks, queues and schedules
Faster async functions and promises
浏览器提供的一些接口,比如 location
、screen
、navigator
、 history
。
起初使用 xml 来描述页面结构,为了标准化,推出了 html,当浏览器通过 url 请求服务器,服务器返回 html 给浏览器,浏览器和 JavaScript 都不认识 html,所以浏览器会把 html 转换成 DOM,DOM 是一个树结构
获取 DOM
// 通过 id 获取
var dom = document.getElementById('box')
//
property 和 attribute的区别
DOM 节点就是一个 js 对象,比如一个 p 节点,可以拥有 class
style
等属性
属于 html 的属性,需要通过 getAttribute 和 setAttribute 来操作属性,改操作会造成重绘和重排,所以尽量避免频繁操作。
Composing Software
author: Eric Elliott
问题【LeetCode 198】:
一个小偷准备去偷一排别墅,但是相邻两个别墅被偷了会触发报警,所以在不出发报警的前提下,如何偷到最多的钱。
用数组表示一排别墅,比如 [1,2,5,2,1,3], index 为0的别墅和 index 为1的别墅相邻,index 为0的别墅可偷的钱为1。
如果是 [1,2,5,2,1,3],小偷偷到最多的钱总和为:1+5+3 = 9
width = device-width
;不允许用户缩放等1. Repetition is allowed:
Such as a permutation lock, the number is '333'.
For example, choose 3 of those things(n), the permutations are:
n*n*n
2. No repetition:
For example the three first people in a running race, you can't be first and second, assume there are five people, the permutations are:
5*4*3
!5 / !(5-3)
choose r from n:
!n / !(n-r)
1. Repetition is allowed
There are five flavors of ice cream: banana, chocolate, lemon, strawberry, vanilla.
We have three scoops, how many variations will there be?
let's use letters for the flavors: {b, c, l, s, v}. Examples selections include:
1. {c,c,c} {three scoops chocolate}
>ooo>>>
2. {b,l,v} (one each of banana, lemon, vanilla)
o>>o>>o
3. {b,v,v} (one scoop of banana, two scoop of vanilla)
o>>>>o
!n / !r * !(n - r)
!(3 + 5 - 1) / !3 * !(5 - 1)
!(r + n - 1) / !r * !((r + n - 1) - r) = !(r + n - 1) / !r * !(n - 1)
2.No repetition
choose 3 from 3
the permutations are:
123
132
213
231
312
321
the combinations are:
123
3! / !(3-3)*!3
choose r from n:
n! / !(n-r)*!r
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.