三种异步方法来输出结果
1)第一种回调
function foo(num){
setTimeout(function(){
num(1);
},2000);
}
foo(function(result){
console.log(result);
}
2)Promise回调
let foo = new Promise ((resolve,reject)=>{
setTimeout(function(){
resolve(1);
},2000);
})
foo.then(result => console.log(result))
3)async await 回调
let fAsync = async () => {
return new Promise((success,error)=>{
setTimeout(()=>{
success(1);
},2000);
}
}
async function test(){
let num = await fAsync();
return num;
}
test().then(console.log)
两数之和
给出一个整型数组 numbers 和一个目标值 target,请在数组中找出两个加起来等于目标值的数的下标,返回的下标按升序排列。
数据范围:2 <= len(numbers) <= 1000
1 <= numbers_i , target <= 10^91
要求:空间复杂度 O(n)O(n),时间复杂度 O(nlogn)
例如:
给出的数组为 [20, 70, 110, 150] , 目标值为90
返回一个数组 [1,2] ,因为 numbers _1+numbers_2=20+70=90
function twoSum( numbers , target ) {
// write code here
let obj = [];
for(let i = 0; i < numbers.length; i++){
for(let j = 0; j < numbers.length; j++){
if(target === numbers[i]+numbers[j] && i!==j){
obj = [i+1,j+1]
}
}
}
return obj.sort(function(a,b){
return a - b
})
}
module.exports = {
twoSum : twoSum
};
反转链表
输入一个长度为n链表,反转链表后,输出新链表的表头。
数据范围n ≤ 1000
要求:空间复杂度 O(1)O(1) ,时间复杂度 O(n)O(n) 。
function ReverseList(pHead)
{
// write code here
let pre = null;
let current = null;
while(pHead){
current = pHead.next;//保存一下当前的指向,也就是下一个的位置
pHead.next = pre;//让当前的phead指向到pre
pre = pHead;//移动原来的pre到下一个节点,原来是null <-- Phead 那就是pHead咯
//此时已完成head结点的摘取及与前一个节点的连接,则我们需要操作下一个结点:故需移动pre和head,让pre指向head,head指向下一个节点。
pHead = current;
}
return pre
}
module.exports = {
ReverseList : ReverseList
};
反转字符串
写出一个程序,接受一个字符串,然后输出该字符串反转后的字符串。
function solve( str ) {
// write code here
return str.split("").reverse().join("");
}
module.exports = {
solve : solve
};
斐波那契数列
function Fibonacci(n)
{
// write code here
if( n == 0){
return 0;
}
else if( n == 1){
return 1;
}
else if( n >1 ){
return Fibonacci( n -2 ) + Fibonacci( n -1 );
}
}
module.exports = {
Fibonacci : Fibonacci
};
判断回文
给定一个长度为 n 的字符串,请编写一个函数判断该字符串是否回文。如果是回文请返回true,否则返回false。
字符串回文指该字符串正序与其逆序逐字符一致。
function judge( str ) {
// write code here
let arr = Array.from(str);
let start = null;
let end = null;
for(let i = 0 ; i < arr.length ; i++){
start = i;
end = arr.length - 1 - i;
if( arr[start]!== arr[end] ){
return false;
}
}
return true;
}
module.exports = {
judge : judge
};
箭头函数和普通函数的区别?箭头函数可以当做构造函数 new 吗?
(1)箭头函数比普通函数更加简洁
- 如果没有参数,就直接写一个空括号即可
- 如果只有一个参数,可以省去参数的括号
- 如果有多个参数,用逗号分割
- 如果函数体的返回值只有一句,可以省略大括号
- 如果函数体不需要返回值,且只有一句话,可以给这个语句前面加一个void关键字。最常见的就是调用一个函数:
let fn = () => void doesNotReturn();
复制代码
(2)箭头函数没有自己的this
箭头函数不会创建自己的this, 所以它没有自己的this,它只会在自己作用域的上一层继承this。所以箭头函数中this的指向在它在定义时已经确定了,之后不会改变。
(3)箭头函数继承来的this指向永远不会改变
var id = 'GLOBAL';
var obj = {
id: 'OBJ',
a: function(){
console.log(this.id);
},
b: () => {
console.log(this.id);
}
};
obj.a(); // 'OBJ'
obj.b(); // 'GLOBAL'
new obj.a() // undefined
new obj.b() // Uncaught TypeError: obj.b is not a constructor
对象obj的方法b是使用箭头函数定义的,这个函数中的this就永远指向它定义时所处的全局执行环境中的this,即便这个函数是作为对象obj的方法调用,this依旧指向Window对象。需要注意,定义对象的大括号{}
是无法形成一个单独的执行环境的,它依旧是处于全局执行环境中。
(4)call()、apply()、bind()等方法不能改变箭头函数中this的指向
var id = 'Global';
let fun1 = () => {
console.log(this.id)
};
fun1(); // 'Global'
fun1.call({id: 'Obj'}); // 'Global'
fun1.apply({id: 'Obj'}); // 'Global'
fun1.bind({id: 'Obj'})(); // 'Global'
复制代码
(5)箭头函数不能作为构造函数使用
构造函数在new的步骤在上面已经说过了,实际上第二步就是将函数中的this指向该对象。 但是由于箭头函数时没有自己的this的,且this指向外层的执行环境,且不能改变指向,所以不能当做构造函数使用。
(6)箭头函数没有自己的arguments
箭头函数没有自己的arguments对象。在箭头函数中访问arguments实际上获得的是它外层函数的arguments值。
(7)箭头函数没有prototype
(8)箭头函数不能用作Generator函数,不能使用yeild关键字
不能new
没有自己的this,不能调用call和apply
没有prototype,new关键字内部需要把新对象的_proto_指向函数的prototype
vuex有哪几种属性
- state 基本数据(数据源存放地)
- getters 从基本数据派生出来的数据
- mutations 提交更改数据的方法,同步
- actions 像一个装饰器,包裹mutations,使之可以异步
- modules 模块化vuex
vuex的mutation中不能做异步操作
vuex中所有状态更新的唯一途径都是mutation,异步操作通过action来提交mutation实现,这样可以方便地跟踪每一个状态的变化,从而能够实现一些工具帮助更好的了解应用。
每个mutation执行完成后都会对应到一个新的状态变更,这样devtools就可以打个快照存下来,然后就实现time-travel了。如果mutation支持异步操作,就没有办法知道状态是如何更新的,无法很好的进行状态的追踪,给调试带来困难。