# 杂项
#### 模板字符串
就是使用
~~~
` `
~~~
在字符串中插入参数。
有个传参方式需要关注,比如,有函数highlight,那么
~~~
highlight`Hello, ${yourName}. I am ${myName}.` // 是可以传进去参数的
~~~
习题:
请你完成 highlight 函数,可以把模版字符串中的插入内容替换掉,并且插入文档以后显示红色。例如:
~~~
const yourName = 'ScriptOJ'
const myName = 'Jerry'
document.body.innerHTML = highlight`Hello, ${yourName}. I am ${myName}.`
~~~
answer:
~~~
const highlight = (...args) => {
console.log(args)
let contents = args[0];
let inputArray = args.slice(1);
let str = '';
for (let i = 0; i < contents.length - 1; i++) {
str += `${contents[i]}<span class='red'>${args[i + 1]}</span>`
}
return str + contents[contents.length - 1];
}
~~~
这里需要注意 args用这个特别的方式传入时,我们可以发现console出来他是这样的:
~~~
[ [ 'Hello, ', '. I am ', '.' ], 'ScriptOJ', 'Jerry' ]
~~~
就是说,数组第一项为分别以参数为断点,切割字符串后的数组,后面一次是模板字符串。且字符串长度为参数个数减1.
#### 逗号操作
逗号操作除了常用的多个声明以外 还可以用于赋值 例如
~~~
var a = (1,2,3,4,5)
~~~
这里a等于5 即最后一个。
#### 不使用中间变量交换a与b的值
```javascript
function swap(a, b) {
b = b - a;
a = b + a; // b 赋值给a
b = a - b; // a赋值给b
return {
a: a,
b: b
}
}
console.log(swap(4, 5));
```
#### 大数相加
```javascript
function bigSum(a, b) {
const strA = a.split('').reverse();
const strB = b.split('').reverse();
let overflow = 0, arrSum = [], maxlength = Math.max(strA.length, strB.length), sum = 0;
for (let i = 0; i < maxlength; i++) {
sum = overflow;
if (i < strA.length) {
sum = sum + parseInt(strA[i]);
}
if (i < strB.length) {
sum = sum + parseInt(strB[i]);
}
arrSum[i] = sum % 10;
overflow = Math.floor(sum / 10);
}
if (overflow !== 0) {
arrSum.push(overflow);
}
return arrSum.reverse().join('');
}
console.log(bigSum('12','13'));
```
#### 输出值
```javascript
var b = 1;
function a(b){
b = 2;
console.log(b);
}
a(b); // 输出2
console.log(b); // 输出1
```
#### 关于闭包
这里f1 f2 算是两个闭包 所以需要从新从零开始计算
~~~
function Foo() {
let i = 0;
return function () {
return i++
}
}
var f1 = Foo();
var f2 = Foo();
console.log(f1()); // 0
console.log(f1()); // 1
console.log(f2()); // 0
~~~
#### Boolean对象相关
因为x是boolean传入的一个false对象。非空对象放入Boolea中 var x = new Boolean(false)返回true x为true。
~~~
const x = new Boolean(false);
if (x) {
console.log('true');
} else {
console.log('false');
}
~~~
#### var相关
~~~
function test() {
var n = 4399;
function add() {
n++
console.log(n);
}
return { n: n, add: add }
}
var result = test()
var result2 = test()
result.add() // 4400
result.add() // 4401
console.log(result.n); // 4399
~~~
#### prototype的设置
prototype不是这么设置的。 需要用prototype.do。
~~~
function A() {
this.do = function () {
console.log('inner');
}
}
A.prototype = function () {
this.do = function () {
console.log('outer');
}
}
var kk = new A();
kk.do();
~~~
#### 变量提升报错
~~~
(function(){
var x = foo()
var foo = function(){
console.log('1221');
}
return x;
})()
~~~
#### 变量相关
~~~
(function () {
var a = b = 3;
})();
console.log("a defined? " + (typeof a !== 'undefined')); // false
console.log("b defined? " + (typeof b !== 'undefined')); // true
console.log(b); // 3
~~~
#### 匿名函数调用,this指向全局
~~~
var myObject = {
foo: "bar",
func: function () {
var self = this;
console.log("outer func: this.foo = " + this.foo); //bar
console.log("outer func: self.foo = " + self.foo); //bar
(function () {
console.log("inner func: this.foo = " + this.foo); //undefined 匿名函数调用this指向全局
console.log("inner func: self.foo = " + self.foo); //bar
}());
}
};
myObject.func();
~~~
#### 函数输出一样么?
~~~
function foo1() {
return {
bar: "hello"
};
}
function foo2() {
return
{
bar: "hello"
};
}
~~~
> 不一样 return break continue 后面如果换行 会默认被跟上';' 就相当于
return;
{
bar:"hello"
}
会return一个undefined
#### 隐式类型转换
~~~
var a = {},
b = { key: 'b' },
c = { key: 'c' };
a[b] = 123; // 这里因为b和c都是object 所以a[b] = a[c] = a["[object Object]"] 所以输出456
a[c] = 456;
console.log(a[b]);
~~~
#### eval
接受字符串,并转化为js 耗性能,不建议使用。
~~~
eval("x=10;y=20;console.log(x*y)")
~~~
#### 避免栈溢出
~~~
var list = readHugeList();
var nextListItem = function() {
var item = list.pop();
if (item) {
// process the list item...
nextListItem(); // 可以把红色部分改为setTimeOut(nextListItem,0)用于优化以免溢出。
}
};
~~~
#### 位运算
关于js的位运算,>>有符号右移 >>> 无符号右移<< 有符号左移 <<<无符号左移
有无符号的运算结果不同,详见:
~~~
-9 >>> 2 (base 10): 00111111111111111111111111111101 (base 2) = 1073741821 (base 10)
-9 >> 2 (base 10): 11111111111111111111111111111101 (base 2) = -3 (base 10)
~~~
#### 逻辑运算符的作用
a()&&b() 如果a()为真,那么则执行b(),并返回b()执行之后的结果;如果a()为假,则返回a的结果。
a()||b() 如果a()为假,那么则执行b(),并返回b()执行之后的结果;如果a()为真,则返回a的结果。
#### toLocaleString
格式化用的
#### 浮点数相加的问题
0.1+0.2!==0.3 是因为二进制1导致的 解决方法 toFixed(dddd)其中括号中的dddd为整数,表示位数
- html
- 冒泡/捕获/委托
- 前端路由
- Dom
- 创建节点API
- 页面修改型API
- 节点查询型API
- 节点关系型API
- 元素属性API
- DOM事件
- classList
- 性能优化
- 节流防抖
- localStorage sessionStorage
- BOM
- meta
- data属性
- js实现拖拽
- html5
- 关于meta
- 轮播图
- js实现拖放
- 电话号inputFormater
- js
- es6
- promise
- iterator
- generator
- async
- proxy
- Set
- Map
- Object的扩展
- String
- Iterator
- Symbol
- 解构赋值
- 函数式编程
- module
- 基本数据类型
- 数组相关codings
- for of/for in
- this
- call bind apply
- 闭包
- 作用域
- prototype与继承
- 深浅拷贝
- setTimeOut/setInterval
- 垃圾处理机制
- 设计模式
- 观察者模式
- 单例模式
- 策略模式
- RegExp
- with
- 其他玩意
- Error/Stack Trace
- 面向对象
- css
- 回流重绘
- %取值
- 属性继承/属性优先级
- flex
- BFC
- 盒模型
- 设置css的方法
- 定位机制
- 块级/行内元素
- hack和一些别的玩意
- css动画
- 几个布局
- 画图形
- css3
- animation对比transform
- 点击不同图片区域跳转不同
- css选择器性能问题
- vh rem em
- css选择器
- 伪类伪元素
- css匹配原理
- 数据结构与算法
- 数据结构
- 树
- 链表
- 栈和队列
- 排序
- 归并排序
- 插入排序
- 选择排序
- 冒泡排序
- 快速排序
- 递归
- 回溯法
- 搜索算法
- 动态规划
- http
- 跨域问题
- CORS
- GET/POST
- ajax
- ajax上传文件
- http缓存
- https
- TCP/UDP
- cookie/session
- http2.0
- spdy
- websocket
- React
- redux
- 生命周期
- 虚拟dom与diff
- 双向数据绑定
- mvvm
- setState
- contextApi props reudx
- 高阶组件
- react-redux
- Fiber
- react-router
- 受控/非受控组件
- 待整理
- webpack
- loader实现
- 前端安全
- 移动端适配
- Vue
- 传值
- 其他