伪数组

伪数组是一种结构对象,具有以下特点

1.具有length属性
2.按照索引方式存储数据
3.不具有数组的push pop方法
4.可以通过Array.prototype.slice

1
2
3
4
5
6
var fake = {
0: 'a',
1: 'b',
2: 'c',
length: 3
}

比如function内的arguments,document.forms和document.getElementsByTagName获取得到的DOM对象集合,及DOM对象的childNodes,jQuery对象集合,都是伪数组。
伪数组是一个Object,真实数组是一个Array

1
2
3
4
5
6
fake instanceof Array === false
Object.prototype.toString.call(fake) === '[object Object]'

var array = [1,2,3,4,5]
array.instanceof Array === true; //true
Object.prototype.toString.call(array) === '[object Array]';

判断伪数组的方法

1
2
Array.isArray(fake) === false;
Array.isArray(array) === true;

伪数组使用数组的方法

1
2
3
4
5
6
7
var arr = Array.prototype.slice(arguments)
var arr = Array.prototype.slice.call(arguments, 0)

Array.prototype.forEach.call(arguments, function(v){

})
[].slice.call(arguments)

理解setTimeout和setInterval

通常使用这两个函数来实现伪异步的效果,但JavaScript是单线程环境下运行的。

1
2
3
4
5
console.log('1');
setTimeout(function(){
console.log('2');
}, 0);
console.log('3');

依次输出 1, 3, 2

1
2
3
4
5
6
7
function fun() {
setTimeout(function(){
console.log('time to show me');
}, 1000);

while(true) {}
}

控制台不会输出”time to show me”。因为无论如何伪装成异步,都无法脱离单线程的环境。
定时器意味这代码在未来某个时间执行,却不能保证具体的时间点。因为页面的生命周期中,不同时间可能有其他代码在控制JavaScript进程。在页面下载完成后代码的运行、事件处理程序、Ajax回调函数都是使用同样的线程,实际上浏览器负责进行排序,指派某段程序在某个时间点运行的优先级。参考

sort排序

sort()函数默认情况下使用字母数字(字符串Unicode码点)排序

1
[1,2,5,10].sort()

输出[1, 10, 2, 5]

1
[1, 2, 5, 10].sort((a, b)=> a-b);

即可得到正确排序的数组。

短路求值

短路求值, 只有当第一个运算数的值无法确定逻辑运算的结果时,才对第二个运算数进行求值:当AND(&&)的第一个运算数的值为false时,其结果必定为false,不在进行第二个运算;当OR(||)的第一个运算数为true时,最后结果必定为true。

条件判断

1
2
3
4
5
6
7
8
9
10
11
const TRUE = true;
let isTrue = () => {
console.log('it is true')
}

if(TRUE) {
isTrue()
}
// 等同于

test && isTrue();

参数设置默认值

1
2
3
4
5
6
let tellYourName = (name) => {
name = name || 'zou'
console.log('my name is ' + name);
}
tellYourName() // my name is zou
tellYourName('yifeng') // my name is yifeng

在JavaScript中,0, ‘’, null, undefined, NaN都会通过弱类型转换,判定为false。

const不可变

ES6中,const声明的变量是不可更改,否则有可能报错。

1
2
const a = 'a';
a = 'b';

报错:”a” is read-only

1
2
3
4
const a = {
name: 'yifeng'
}
a.name = 'zou';

这种情况下更改const声明的变量,没有报错。原因是JavaScript中的对象是引用类型,返回的是内存中的存储地址,更改对象的属性值,并不会改变对象所在的内存地址。

箭头函数的this

箭头函数的this指向的是函数定义时的this,普通函数的this指向调用时的this。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
var x =1,
a = {
x: 2,
funA: () => {
console.log(this.x)
},
funB() {
console.log(this.x)
}
}

a.funA(); // 1
a.funA.call(a); // 1
a.funB(); // 2

箭头函数没有自己的this值,箭头函数内的this值继承自外围作用域。外层函数的this指向改变,箭头函数的this就会改变,但这种关系是不会改变。
如下代码

1
2
3
4
5
6
7
8
9
10
function test() {
setTimeout(()=>{
console.log(this.a)
}, 100)
}

var a = 'aa'

test() // aa
test.call({a: 'bb'}) // bb

test函数在babel下的实现

1
2
3
4
5
6
7
8
9
'use strict';

function test() {
var _this = this;

setTimeout(function () {
console.log(_this.a);
}, 100);
}

除了this,箭头函数也没有arguments,super等概念。