彻底弄懂bind,apply,call三者的区别

为什么要改变 this 指向?

例子:

1
2
3
4
5
6
7
8
9
var name = 'lucy';
let obj = {
name : "martin",
say : function(){
console.log(this.name);
}
}
obj.say(); // martin this指向obj对象
setTimeout(obj.say,0); // lucy ,this 指向 window 对象

可以观察到,正常情况下 say 方法中的 this 是指向调用它的 obj 对象的,而定时器 setTimeout 中的 say 方法中 this 是指向 window 对象的(浏览器中),这是因为 say 方法在定时器中是作为回调函数来执行的,因此回到主线执行时是在全局执行上下文的环境中执行的,但我们需要的是 say 方法中 this 指向对象 obj 对象,因此我们需要修改 this 的指向。

阅读更多

10小时掌握前端面试题

1、call 、apply 、bind 的区别是什么?哪个性能更好一些?

性能测试:

1
2
3
console.time('A');
执行代码
console.timeEnd('A');

浏览器自带性能测试

2、实现(5).add(3).minus(2) ,使其输出结果为:6

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
(function() {
// 每一个方法执行完,都要返回 Number 这个类的实例,这样才可以继续调取 Number 类原型中的方法(链式写法)
function checkNumber(n) {
n = Number(n);
return isNaN(n) ? 0 : n;
}
function add(n) {
n = checkNumber(n);
return this + n;
}
function minus(n) {
n = checkNumber(n);
return this - n;
}
["add", "minus"].forEach(item => {
Number.prototype[item] = eval(item);
});
})();

以上是我对下列视频及文章的归纳和总结。
10 小时掌握前端面试题

中高级前端大厂面试秘籍,为你保驾护航金三银四,直通大厂

CSS

盒模型

content-box (W3C 标准盒模型)
border-box (IE 盒模型)
padding-box
margin-box (浏览器未实现)

BFC

块级格式化上下文,是一个独立的渲染区域,让处于 BFC 内部的元素与外部的元素相互隔离,使内外元素的定位不会相互影响。
IE 下为 Layout,可通过 zoom:1 触发
触发条件:
根元素
position: absolute/fixed
display: inline-block / table
float 元素
ovevflow !== visible
规则:
属于同一个 BFC 的两个相邻 Box 垂直排列
属于同一个 BFC 的两个相邻 Box 的 margin 会发生重叠
BFC 中子元素的 margin box 的左边, 与包含块 (BFC) border box 的左边相接触 (子元素 absolute 除外)
BFC 的区域不会与 float 的元素区域重叠
计算 BFC 的高度时,浮动子元素也参与计算
文字层不会被浮动层覆盖,环绕于周围
应用:
阻止 margin 重叠
可以包含浮动元素 —— 清除内部浮动(清除浮动的原理是两个 div 都位于同一个 BFC 区域之中)
自适应两栏布局
可以阻止元素被浮动元素覆盖

层叠上下文

触发条件
根层叠上下文(html)
position
css3 属性
flex
transform
opacity
filter
will-change
-webkit-overflow-scrolling
层叠等级:层叠上下文在 z 轴上的排序
在同一层叠上下文中,层叠等级才有意义
z-index 的优先级最高
层叠等级

居中布局
水平居中
行内元素:text-align:center
块级元素:margin: 0 auto

Taro 从入门到实战

配置文件

更改端口号和域名:

config/index.js

1
2
h5: {
devServer:{ host: 'localhost', port: 8888},

更改 appid:
project.config.json(小程序独有的配置文件)

1
"appid": "touristappid",
阅读更多

变量的解构赋值

解构赋值语法是一种 JavaScript 表达式。通过解构赋值,可以将属性值从对象/数组中取出,赋值给其他变量。

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
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
// 解构数组
var foo = ["one", "two", "three"];

var [one, two, three] = foo;
console.log(one); //'one'
console.log(two); //'two'
console.log(three); // 'three'

var a, b;
[a, b] = [1, 2];
console.log(a); // 1
console.log(b); // 2

// 默认值

var a, b;
[a = 5, b = 7] = [1];
console.log(a); // 1
console.log(b); // 7

// 交换变量

var a = 1;
var b = 3;

[a, b] = [b, a];
console.log(a); // 3
console.log(b); // 1

// 解析一个从函数返回的数组

function f() {
return [1, 2];
}

var a, b;
[a, b] = f();
console.log(a); // 1
console.log(b); // 2

// 忽略某些值

function f() {
return [1, 2, 3];
}

var [a, , b] = f();
console.log(a); // 1
console.log(b); // 3

// 将剩余数组赋值给一个变量

var [a, ...b] = [1, 2, 3];
console.log(a); // 1
console.log(b); // [2,3]

// 用正则表达式匹配提取值

function parseProtocol(url) {
var parsedURL = /^(\w+)\:\/\/([^\/]+)\/(.*)$/.exec(url);
if (!parsedURL) {
return false;
}
console.log(parsedURL); // ["https://developer.mozilla.org/en-US/Web/JavaScript", "https", "developer.mozilla.org", "en-US/Web/JavaScript"]

var [, protocol, fullhost, fullpath] = parsedURL;
return fullhost;
}

console.log(
parseProtocol("https://developer.mozilla.org/en-US/Web/JavaScript"); // "https"
);

// 解构对象

var o = {p:42,q:true};
var {p,q} = o;

console.log(p); // 42
console.log(q); // true

// 无声明赋值

var a,b;
({a,b} = {a : 1,b : 2})

// 给新的变量名赋值

var o = {p:42,q:true};
var {p:foo,q:bar} = o;

console.log(foo); // 42
console.log(bar); // true

// 默认值

var {a = 10,b = 5} = {a : 3};
console.log(a);
console.log(b);

// 解构嵌套对象和数组

const metadata = {
title: 'Scratchpad',
translations: [
{
locale: 'de',
localization_tags: [],
last_edit: '2014-04-14T08:43:37',
url: '/de/docs/Tools/Scratchpad',
title: 'JavaScript-Umgebung'
}
],
url: '/en-US/docs/Tools/Scratchpad'
};

let {
title: englishTitle, // rename
translations: [
{
title: localeTitle, // rename
},
],
} = metadata;

console.log(englishTitle); // "Scratchpad"
console.log(localeTitle); // "JavaScript-Umgebung"

// For of 迭代和解构

var people = [
{
name: 'Mike Smith',
family: {
mother: 'Jane Smith',
father: 'Harry Smith',
sister: 'Samantha Smith'
},
age: 35
},
{
name: 'Tom Jones',
family: {
mother: 'Norah Jones',
father: 'Richard Jones',
brother: 'Howard Jones'
},
age: 25
}
];

for (var {name: n, family: {father: f}} of people) {
console.log('Name: ' + n + ', Father: ' + f);
// "Name: Mike Smith, Father: Harry Smith"
// "Name: Tom Jones, Father: Richard Jones"
}

// 从作为函数实参的对象中提取数据

function userId({id}) {
return id;
}

function whois({displayName: displayName, fullName: {firstName: name}}){
console.log(displayName + " is " + name);
}

var user = {
id: 42,
displayName: "jdoe",
fullName: {
firstName: "John",
lastName: "Doe"
}
};

console.log("userId: " + userId(user)); // "userId: 42"
whois(user); // "jdoe is John"


以上是我对下列视频及文章的归纳和总结。
ES6 免费视频教程

参考资料:
MDN 解构赋值
ECMAScript 6 入门-变量解构赋值

相关代码仓库:
ES6

新的声明方式

声明方式
var 声明语句声明一个变量,并可选地将其初始化为一个值。

语法:

1
var varname1 = [= value1][, varname2][= value2]...[, varnameN][=valueN];

varname
变量名。变量名可以定义为任何合法标识符。
valueN
变量的初始化值。默认值是 undefined。

描述:
变量声明,无论发生在何处,都在执行任何代码之前进行处理
用var声明的变量的作用域是它当前的执行上下文。
重新声明一个 JavaScript 变量,它将不会丢失其值。
将赋值给未声明变量的值在执行赋值时将其隐式地创建为全局变量(它将成为全局对象的属性)。

阅读更多

ES6的开发环境搭建

使用Babel把ES6编译成ES5

  1. 运行以下命令安装软件包

    1
    2
    npm install --save-dev @babel/core @babel/cli @babel/preset-env
    npm install --save @babel/polyfill
  2. 在项目根目录中创建.babelrc文件

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    {
    "presets": [
    [
    "@babel/preset-env",
    {
    "targets": {
    "edge": "17",
    "firefox": "60",
    "chrome": "67",
    "safari": "11.1",
    },
    "useBuiltIns": "usage",
    }
    ]
    ]
    }
  3. 运行下面命令,将src目录中的所有代码编译到dist
    npx babel src -d dist

以上是我对下列视频及文章的归纳和总结。
ES6 免费视频教程

参考资料:
ES6的开发环境搭建

相关代码仓库:
ES6

如何告别 if else

实际例子:不同管理员权限不一样,能够行使的操作也不一样。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
publicclassJudgeRole{
publicString judge(String roleName ) {
String result = "";
if (roleName.equals( "ROLE_ROOT_ADMIN" )) { // 系统管理员有A权限
result = "ROLE_ROOT_ADMIN: " + "has AAA permission" ;
}elseif( roleName.equals("ROLE_ORDER_ADMIN") ) { // 订单管理员有B权限
result = "ROLE_ORDER_ADMIN: " + "has BBB permission" ;
}elseif( roleName.equals("ROLE_NORMAL") ) {// 普通用户有C权限
result = "ROLE_NORMAL: " + "has CCC permission" ;
}else{
result = "XXX" ;
}
return result;
}
}
阅读更多

GitHub 技巧

GitHub 访问和下载

问题:GitHub 访问不了或下载慢
原因:GitHub 的 CDN 被墙屏了。
解决方法:绕过 DNS 解析,在本地直接绑定 host,该方法也可用于其他 CDN 被屏蔽的网站。
原理:找出 GitHub 域名所对应的 IP 地址,直接添加在本地 host 中。每次请求 GitHub 时就无需再向 DNS 查询地址。
操作:

  1. 访问ipaddress,查看网站域名对应的 IP 地址,输入网址则可查阅对应的 IP 地址。

  2. 修改 host 文件
    Windows 中 host 文件在 C:\Windows\System32\drivers\etc 下。
    修改 host 文件如下:

    1
    2
    3
    4
    5
    6
    # localhost name resolution is handled within DNS itself.
    # 127.0.0.1 localhost
    # ::1 localhost

    192.30.253.112 github.com
    151.101.113.194 github.global.ssl.fastly.net
  3. 刷新 DNS
    Windows:cmd 执行 ipconfig/flushdns
    mac:sudo dscacheutil –flushcache

阅读更多
You need to set client_id and slot_id to show this AD unit. Please set it in _config.yml.