【译】12个提升你javascript能力的概念
栏目: JavaScript · 发布时间: 5年前
内容简介:javascript 是一门复杂的语言。如果你是一名 javascript 开发者,理解它的一些基础概念是很重要的。本文选取了 12 个 JS 开发者应该掌握的概念,但不代表 JS 开发者需要了解的全部内容。注意:我会在 github 仓库理解 javascript 中如何分配变量的值是写好代码的基础。如果你还不了解这些,你可能很容易写出无意中修改值的代码。
javascript 是一门复杂的语言。如果你是一名 javascript 开发者,理解它的一些基础概念是很重要的。本文选取了 12 个 JS 开发者应该掌握的概念,但不代表 JS 开发者需要了解的全部内容。
注意:我会在 github 仓库 JS Tips & Tidbits 上持续更新这个列表,如果有兴趣欢迎 star。
1. 值 VS 引用
理解 javascript 中如何分配变量的值是写好代码的基础。如果你还不了解这些,你可能很容易写出无意中修改值的代码。
javascript 总是 按值分配
变量。但是请 特别
注意:当分配的值是 javascript 的 5 种原始类型( boolean
null
undefined
string
number
)时,是分配的真正的值。而如果分配的值是 Array
Function
Object
时,只会分配该对象在内存中的一个引用。
举个例子。在下面的代码中,var2 被赋值为 var1。因为 var1 是原始类型(string),var2 的值就是 var1 的 值,并且与 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' } 复制代码
如果你期望像分配原始类型那样的结果,这里就会出现问题,修改 var2 同样会影响到 var1。如果你创建了一个无意中修改对象的函数,就可能有难以预料的错误。
2. 闭包
闭包是 javascript 中很重要的特性,可以实现变量的私有访问。在下面的例子中,createGreeter 返回了一个匿名函数,函数可以访问外层函数的 greeting 参数。
function createGreeter(greeting) { return function(name) { console.log(greeting + ', ' + name); }; } const sayHello = createGreeter('Hello'); sayHello('Joe'); // Hello, Joe 复制代码
在实际编码中,你可能希望有一个初始化函数 apiConnect(apiKey) 能够返回某些方法会用到的 apiKey。这种情况下,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' 复制代码
下面的例子中,解构用来干净地将 person 对象传递给 introduce 函数。或者说,解构可以(经常)用来提取传递给函数的参数的属性。如果你熟悉 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 不能接收一个数组,而是接收单个值作为参数。展开运算符 ...
就是用来把数组里的元素一个一个拉出来。
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 的数组方法经常能让你很优雅、便捷地转换你想要的数据。我经常看到有关如何以某种方式操纵对象数组的问题。这正是数组方法的可用之处。
我将在这里介绍一些不同的数组方法,以类似的可能会混淆的方法来分类。这个列表并不全面,我鼓励你们在MDN 上反复复习并练习这些方法。
map, filter, reduce
有人可能对这 3 个方法有些混乱。但这些都是转换数组或返回聚合值的有用方法。
- 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] 复制代码
- reduce :累加函数中指定的值。
const arr = [1, 2, 3, 4, 5, 6]; const reduced = arr.reduce((total, current) => total + current); console.log(reduced); // 21 复制代码
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
之后的元素都满足条件,但只会返回第一个匹配元素。
- findIndex :和 find 的机制基本一样,只是会返回第一个匹配元素的索引值而不是返回该元素。来看下面的例子:
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 复制代码
push, pop, shift, unshift
这是一组很棒的数组方法,可以让你有针对性地添加或删除数组中的元素。
- 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 复制代码
splice, slice
这 2 个方法会修改数组或返回一个子数组。
- splice :通过删除或替换已存在的元素或插入新的元素来修改原数组的内容。会修改原数组。
下面的例子可以理解为:在索引为 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'] 复制代码
sort
- sort :基于提供的函数对数组进行排序,该函数接收 2 个参数,代表需要 排序 的 2 个数组元素。会修改原数组。如果函数返回负值或 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] 复制代码
你是否已经全部理解了呢?我还没有。事实上,我在写这篇文章的时候也经常参考 MDN 文档——没关系!只要知道有什么样的方法就可以了。
7. Generators
不要害怕 *
。生成器函数指定了下次调用 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. === VS ==
确信你已经了解了 ===
与 ==
的差异。在进行比较时, ==
会进行类型转换, ===
则不会。
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 复制代码
复习下之前的 值 VS 引用 章节,保证能完全理解将一个引用变量赋值给其他变量时,其实是赋值了内存中同一对象的相同引用给其他变量。
10. 回调函数
许多人都会被 javascript 的回调函数吓到!其他它们很简单,来看例子。 console.log
作为回调函数传递给了 myFunc
。当计时器就绪时执行。
function myFunc(text, callback) { setTimeout(function() { callback(text); }, 2000); } myFunc('Hello world!', console.log); // 'Hello world!' 复制代码
11. Promises
一旦你理解的回调函数,你就会陷入 回调地狱 。然后 Promises 解决了问题。在 Promise 中包裹你的异步逻辑,成功时调用 resolve,失败时调用 reject。使用 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. Async Await
一旦你掌握了 Promises
,你就会喜欢 async/await
,它是基于 promises 的语法糖。下面的例子中我们使用了 async
函数,在函数里使用了 await
来处理 greeter
。
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能力的概念》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
叠加体验:用互联网思维设计商业模式
穆胜 / 机械工业出版社 / 2014-11 / 39.00
本书在互联网思维改变一切的背景下,详细介绍了如何运用互联网思维重构商业模式,主要包括以下内容:①互联网经济中的商业逻辑(即“互联网思维”),不仅给出了消费方面的逻辑变革,还给出了在生产端的逻辑变革以及“跨界”的逻辑变革。②给出了一个“三层产品体验模型”,厘清了互联网思维,打造完美终端、云端服务和价值群落三层体验,企业可以选择做不同层面的体验组合,这即是选择了不同的市场策略。但是,企业要基业长青,终......一起来看看 《叠加体验:用互联网思维设计商业模式》 这本书的介绍吧!
图片转BASE64编码
在线图片转Base64编码工具
HSV CMYK 转换工具
HSV CMYK互换工具