javascript 开发
JavaScript是一种复杂的语言。 如果您是任何级别JavaScript开发人员,那么一定要了解其基本概念。 本文讨论了12个对任何JS开发人员都至关重要的概念,但绝不能代表JS开发人员应了解的全部内容。
我将在名为JS Tips&Tidbits的Github存储库中不断更新此列表。 如果您想继续,请加注⭐和分享!
1.值与参考变量分配
了解JavaScript如何分配变量是编写无错误JavaScript的基础。 如果您不理解这一点,则可以轻松编写无意间更改值的代码。
JavaScript 始终按值分配变量。 但是这部分非常重要:当分配的值是JavaScript的五种原始类型之一(即Boolean,null,undefined,String和Number)时,将分配实际值。 但是,当分配的值是数组,函数或对象时,将分配对内存中对象的引用 。
时间示例! 在以下代码段中,将var2设置为等于var1。 由于var1是原始类型(字符串),因此将var2设置为等于var1的String值,并且此时可以认为与var1完全不同。 因此,重新分配var2对var1无效。
let var1 = 'My string' ;
let var2 = var1;var2 = 'My new string' ; console .log(var1);
// 'My string'
console .log(var2);
// 'My new string'
让我们将此与对象分配进行比较。
let var1 = { name : 'Jim' }
let var2 = var1;var2.name = 'John' ; console .log(var1);
// { name: 'John' }
console .log(var2);
// { name: 'John' }
如果您期望像原始分配这样的行为,可能会发现这可能会引起问题! 如果您创建了一个无意间使一个对象变异的函数,这将变得尤为难看。
2.关闭
闭包是一种重要JavaScript模式,可用于私有访问变量。 在此示例中,createGreeter返回一个匿名函数,该函数可以访问提供的问候语“ Hello”。 对于将来的所有使用,sayHello将可以访问此问候语!
function createGreeter ( greeting ) {
return function ( name ) {
console .log(greeting + ', ' + name);
}
} const sayHello = createGreeter( 'Hello' );
sayHello( 'Joe' );
// Hello, Joe
在更实际的场景中,您可以设想一个初始函数apiConnect(apiKey),该函数返回一些将使用API密钥的方法。 在这种情况下,只需要再次提供apiKey就可以了。
function apiConnect ( apiKey ) {
function get ( route ) {
return fetch( ` ${route} ?key= ${apiKey} ` );
} function post ( route, params ) {
return fetch(route, {
method : 'POST' ,
body : JSON .stringify(params),
headers : {
'Authorization' : `Bearer ${apiKey} `
}
})
} return { get, post }
} const api = apiConnect( 'my-secret-key' ); // No need to include the apiKey anymore
api.get( 'http://www.example.com/get-endpoint' );
api.post( 'http://www.example.com/post-endpoint' , { name : 'Joe' });
3.解构
不要被JavaScript参数解构抛弃! 这是从对象中干净地提取属性的常用方法。
const obj = {
name : 'Joe' ,
food : 'cake'
} const { name, food } = obj; console .log(name, food);
// 'Joe' 'cake'
如果要提取其他名称的属性,则可以使用以下格式指定它们。
const obj = {
name : 'Joe' ,
food : 'cake'
} const { name : myName, food : myFood } = obj; console .log(myName, myFood);
// 'Joe' 'cake'
在以下示例中,使用解构将个人对象干净地传递给Introduction函数。 换句话说,解构可以(经常)直接用于提取传递给函数的参数。 如果您熟悉React,您可能以前已经看过!
const person = {
name : 'Eddie' ,
age : 24
} function introduce ( { name, age } ) {
console .log( `I'm ${name} and I'm ${age} years old!` );
} console .log(introduce(person));
// "I'm Eddie and I'm 24 years old!"
4.传播语法
可以将人们拒之门外但相对简单JavaScript概念是传播运算符! 在以下情况下,无法将Math.max应用于arr数组,因为它没有将数组作为参数,而是将各个元素作为参数。 扩展运算符...用于将单个元素拉出数组。
const arr = [ 4 , 6 , -1 , 3 , 10 , 4 ];
const max = Math .max(...arr);
console .log(max);
// 10
5.休息句法
让我们谈谈JavaScript剩余语法。 您可以使用它将传递给函数的任意数量的参数放入数组中!
function myFunc ( ...args ) {
console .log(args[ 0 ] + args[ 1 ]);
}myFunc( 1 , 2 , 3 , 4 );
// 3
6.数组方法
JavaScript数组方法通常可以为您提供令人难以置信的优雅方式来执行所需的数据转换。 作为StackOverflow的贡献者,我经常看到有关如何以一种或另一种方式操纵对象数组的问题。 这往往是数组方法的完美用例。
我将在这里介绍许多不同的数组方法,这些方法是由有时会合并的类似方法组织的。 该列表绝不是全面的:我鼓励您回顾和实践在MDN (我最喜欢JavaScript参考) 上讨论的所有内容 。
1.映射,过滤,缩小
JavaScript数组方法map,filter,reduce周围有些混乱。 这些是转换数组或返回聚合值的有用方法。
- map:返回数组,其中每个元素均按照函数的指定进行转换
const arr = [ 1 , 2 , 3 , 4 , 5 , 6 ];
const mapped = arr.map( el => el + 20 ); console .log(mapped);
// [21, 22, 23, 24, 25, 26]
- filter:返回元素数组,其中函数返回true
const arr = [ 1 , 2 , 3 , 4 , 5 , 6 ];
const filtered = arr.filter( el => el === 2 || el === 4 ); console .log(filtered);
// [2, 4]
- 减少:累积函数中指定的值
const arr = [ 1 , 2 , 3 , 4 , 5 , 6 ];
const reduced = arr.reduce( ( total, current ) => total + current); console .log(reduced);
// 21
2. find,findIndex,indexOf
数组方法find,findIndex和indexOf通常可以合并。 如下使用它们。
- find :返回符合指定条件的第一个实例。 不会继续查找任何其他匹配实例。
const arr = [ 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 ];
const found = arr.find( el => el > 5 ); console .log(found);
// 6
再次注意,虽然5之后的所有内容都符合条件,但仅返回第一个匹配元素。 实际上,这在发现匹配项时通常会中断for循环的情况下非常有用!
- findIndex :查找几乎相同,但是返回第一个匹配元素的索引而不是返回第一个匹配元素。 以下面的示例为例,该示例使用名称而不是数字。
const arr = [ 'Nick' , 'Frank' , 'Joe' , 'Frank' ];
const foundIndex = arr.findIndex( el => el === 'Frank' );
console .log(foundIndex);
// 1
- indexOf:的工作原理几乎与findIndex相同,但是它采用一个简单的值而不是将函数作为参数。 您可以在逻辑更简单并且不需要使用函数检查是否存在匹配项时使用此方法。
const arr = [ 'Nick' , 'Frank' , 'Joe' , 'Frank' ];
const foundIndex = arr.indexOf( 'Frank' );
console .log(foundIndex);
// 1
3.推,弹出,移位,不移位
有很多很棒的数组方法可以帮助有针对性地从数组中添加或删除元素。
- push:这是一种相对简单的方法,可将项目添加到数组的末尾。 它就地修改数组,函数本身返回添加到数组的项目。
let arr = [ 1 , 2 , 3 , 4 ];
const pushed = arr.push( 5 ); console .log(arr);
// [1, 2, 3, 4, 5]
console .log(pushed);
// 5
- pop:这将从数组中删除最后一项。 同样,它会修改数组。 该函数本身返回从数组中删除的项目。
let arr = [ 1 , 2 , 3 , 4 ];
const popped = arr.pop(); console .log(arr);
// [1, 2, 3]
console .log(popped);
// 4
- shift:这将从数组中删除第一项。 同样,它会修改数组。 该函数本身返回从数组中删除的项目。
let arr = [ 1 , 2 , 3 , 4 ];
const shifted = arr.shift(); console .log(arr);
// [2, 3, 4]
console .log(shifted);
// 1
- unshift:这会将一个或多个元素添加到数组的开头。 同样,它会修改数组。 与许多其他方法不同,该函数本身返回数组的新长度。
let arr = [ 1 , 2 , 3 , 4 ];
const unshifted = arr.unshift( 5 , 6 , 7 ); console .log(arr);
// [5, 6, 7, 1, 2, 3, 4]
console .log(unshifted);
// 7
4.拼接,切片
这些方法可以修改或返回数组的子集。
- 拼接:通过删除或替换现有元素和/或添加新元素来更改数组的内容。 此方法在适当的位置修改数组。
以下代码示例可以读取为:在数组的位置1处,删除0个元素并插入b。
let arr = [ 'a' , 'c' , 'd' , 'e' ];
arr.splice( 1 , 0 , 'b' )
- slice:从指定的开始位置到指定的结束位置之前,返回数组的浅表副本。 如果未指定结束位置,则返回数组的其余部分。 重要的是,此方法不会就地修改数组,而是返回所需的子集。
let arr = [ 'a' , 'b' , 'c' , 'd' , 'e' ];
const sliced = arr.slice( 2 , 4 ); console .log(sliced);
// ['c', 'd']
console .log(arr);
// ['a', 'b', 'c', 'd', 'e']
5.排序
- sort:根据提供的函数对数组进行排序 ,该函数带有第一个元素和第二个元素参数。 修改数组到位。 如果函数返回负数或0,则顺序保持不变。 如果为正,则切换元素顺序。
let arr = [ 1 , 7 , 3 , -1 , 5 , 7 , 2 ];
const sorter = ( firstEl, secondEl ) => firstEl - secondEl;
arr.sort(sorter); console .log(arr);
// [-1, 1, 2, 3, 5, 7, 7]
ew,您抓到所有这些了吗? 我也没有。事实上,我在编写此文档时不得不参考MDN文档-没关系! 只需知道有什么方法可以帮助您达到95%的方法。
7.发电机
不要害怕*。 生成器函数指定下次调用next()时产生的值。 可以具有有限数量的yield,此后next()返回一个未定义的值,或使用循环返回无限数量的值。
function * greeter () {
yield 'Hi' ;
yield 'How are you?' ;
yield 'Bye' ;
} const greet = greeter(); console .log(greet.next().value);
// 'Hi'
console .log(greet.next().value);
// 'How are you?'
console .log(greet.next().value);
// 'Bye'
console .log(greet.next().value);
// undefined
并对无限值使用生成器:
function * idCreator () {
let i = 0 ;
while ( true )
yield i++;
} const ids = idCreator(); console .log(ids.next().value);
// 0
console .log(ids.next().value);
// 1
console .log(ids.next().value);
// 2
// etc...
8.身份运算符(===)与平等运算符(==)
请确保了解JavaScript中的标识运算符(===)和相等运算符(==)之间的区别! ==运算符将在比较值之前进行类型转换,而===运算符将在比较之前不进行任何类型转换。
console .log( 0 == '0' );
// true
console .log( 0 === '0' );
// false
9.对象比较
我看到JavaScript新手犯的一个错误是直接比较对象。 变量指向内存中对象的引用,而不是对象本身! 实际比较它们的一种方法是将对象转换为JSON字符串。 但是,这样做有一个缺点:无法保证对象属性顺序! 比较对象的一种更安全的方法是引入专门用于深度对象比较的库(例如lodash的isEqual )。
以下对象看起来相等,但实际上它们指向不同的引用。
const joe1 = { name : 'Joe' };
const joe2 = { name : 'Joe' }; console .log(joe1 === joe2);
// false
相反,由于将一个对象设置为与另一个对象相等,因此指向相同的引用(内存中只有一个对象),因此以下内容为true。
const joe1 = { name : 'Joe' };
const joe2 = joe1;
console .log(joe1 === joe2);
// true
请务必查看上面的“值与引用”部分,以充分理解将一个变量设置为等于另一个指向内存中对象引用的变量的后果!
10.回调函数
太多的人被JavaScript回调函数吓倒了! 他们很简单,以这个例子为例。 console.log函数将作为回调传递给myFunc。 setTimeout完成时将执行它。 这里的所有都是它的!
function myFunc ( text, callback ) {
setTimeout( function () {
callback(text);
}, 2000 );
}myFunc( 'Hello world!' , console .log);
// 'Hello world!'
11.承诺
了解JavaScript回调后,您很快就会陷入嵌套的“回调地狱”。 这是Promises帮助的地方! 将您的异步逻辑包装在Promise中,并在成功时解决或在失败时拒绝。 使用“ then”来处理成功,使用catch来处理失败。
const myPromise = new Promise ( function ( res, rej ) {
setTimeout( function () {
if ( Math .random() < 0.9 ) {
return res( 'Hooray!' );
}
return rej( 'Oh no!' );
}, 1000 );
});myPromise
.then( function ( data ) {
console .log( 'Success: ' + data);
})
.catch( function ( err ) {
console .log( 'Error: ' + err);
});
// If Math.random() returns less than 0.9 the following is logged:
// "Success: Hooray!"
// If Math.random() returns 0.9 or greater the following is logged:
// "Error: On no!"
12.异步等待
一旦掌握了JavaScript的承诺,您可能会喜欢async await,这只是在promise之上的“语法糖”。 在下面的示例中,我们创建一个异步函数,并在其中等待迎接者答应。
const greeter = new Promise ( ( res, rej ) => {
setTimeout( () => res( 'Hello world!' ), 2000 );
}) async function myFunc () {
const greeting = await greeter;
console .log(greeting);
}myFunc();
// 'Hello world!'
结论
如果您不了解这12个概念中的任何一个,那么您可能至少对JavaScript有了一点了解! 而且,如果您了解所有这些知识,那么希望这是一次练习和增进知识的机会。 您认为哪些其他重要概念? 在评论中让我知道。
翻译自: https://hackernoon.com/12-javascript-concepts-that-will-level-up-your-development-skills-ha1a364w
javascript 开发