存档2021-01-18

How Fast is the 5G of iPhone 12? We did the test and got the answer

Following the release of 5G mobile phones by mobile phone brands such as Huawei, Samsung and Xiaomi, Apple, which once led the technological trend, finally released its first 5G mobile phone-iPhone 12 series. This announced that Apple has officially joined the 5G track, and with Apple’s influence, the iPhone series’ promotion of 5G is also very worth looking forward to.

As we all know, 5G is known for being fast, but do you know how fast the Apple iPhone 12 series phones are in use? The global sales of the iPhone 12 series make it possible for us to test this topic in order to get preliminary results with reference value.


iPhone 12 launch drives spikes in 5G testing

The daily count of unique devices worldwide that are capable of connecting to 5G jumped dramatically when each new iPhone 12 variant launched. We saw a 138.3% increase when comparing the day the iPhone 12 5G and iPhone 12 Pro 5G were released to the mean of the previous week. On the day the iPhone 12 Mini 5G and iPhone 12 Pro Max 5G launched, there was a further 44.3% increase over that one-day spike.

Daily-Trend_5G-Capable-Devices_Year_0121-1


Pro 5G and Pro Max 5G are the most popular iPhone 12 models

We examined Speedtest® results from the launch date of each model through the end of the year to see which iPhone 12 models are the most popular in 15 major cities across the globe. We found that most Speedtest users have opted for the “Pro” models. The iPhone 12 Pro Max 5G showed the highest number of samples among iPhone models in Singapore, Dubai, Hong Kong, New York, Riyadh and Sydney. The iPhone 12 Pro 5G showed the most samples in London, Madrid, Rome, Helsinki, Zürich, Berlin, Amsterdam, Seoul and Tokyo. While the more affordable models were less popular than the Pro models across all the cities on our list, the iPhone 12 Mini saw the most adoption in Tokyo and the iPhone 12 5G saw the most adoption in Rome.

iPhone-12-Model-Popularity_0121


Seoul tops list of iPhone 12 5G speeds

We analyzed Speedtest Intelligence® data for iPhone 12 devices in the same 15 cities and found that Seoul had the fastest median speed over 5G, followed by Dubai and Riyadh. Seoul also had the fastest upload speed by a considerable margin. This is not a surprise given reports that there are more than 100K 5G base stations in South Korea. It is interesting to note that European cities are relatively close to each other in terms of median download and upload speeds. That is good news for the 5G action plan of the European Commission and their target of having uninterrupted 5G coverage on major terrestrial transport paths by 2025.

iPhone-12-5G-Median-Speeds_0121

Elsewhere on the globe mid-band (specifically the 3300-3800 MHz range in most countries) is the most common frequency range for initial 5G roll-outs. There are several reasons for this, ranging from principles of electromagnetic wave propagation to marketing strategies. High-band frequency ranges (above 24 GHz with 400-800 MHz contiguous bandwidth) can do wonders in terms of download speeds, but due to limited propagation characteristics, it can be challenging to provide a mmWave coverage layer across entire markets. In order to mitigate this well-known challenge, operators tend to rely on the lower frequency bands for coverage and selectively deploy mmWave applications in targeted areas (such as high-traffic locations).

Depending on market dynamics and spectrum availability, most providers choose non-standalone (NSA) 5G configuration with an LTE anchor. Operators with limited amounts of FR1 spectrum tend to use dynamic spectrum sharing (DSS), a feature which allows both LTE and New Radio (NR) operation on the same slice of spectrum at the same time. This feature enables a relatively easy deployment of 5G coverage layers, and is a stepping stone to standalone 5G (5G SA). In addition to these commonly observed strategies, a few operators are considering pushing the limits of digital convergence with open radio access networks (RAN).

No matter which strategy an operator chooses, one important fact about 5G does not change: access to a trio of low, mid and high bands and a strategy for rolling out 5G SA is critical. Deployment of the 5G SA core unlocks the potential of enhanced mobile broadband (eMBB), ultra-reliable low latency communication (uRLLC) and massive machine type communications (mMTC).


Operator breakdown: iPhone 12 performance in select cities

5G deployments vary greatly from country to country, depending on spectrum allocated and the particular channel bandwidths each operator has deployed. This makes comparisons between countries difficult, as these factors directly impact the peak 5G speeds achievable in that market. However, looking at four major cities, we can see that performance by operator also varies.

iPhone-12-5G-Median-Speeds_Seoul_0121

In Seoul, the fastest city for 5G on the list above, the 3.5 GHz (Band n78) is used with 80 to 100 MHz channels per operator, and B2C mmWave (which would add a whopping 800 MHz channels per operator) is on the horizon. Here, LG U+ showed the fastest median download speed over 5G on the iPhone 12 in Seoul at 625.03 Mbps. SK Telecom was second and KT third.

iPhone-12-5G-Median-Speeds_Hong-Kong_0121

The three Hong Kong mobile operators that launched commercial 5G networks on April 1, 2020 ranked fastest for iPhone 12 5G median download speed rankings in Hong Kong. China Mobile HK, the only 5G network provider in Hong Kong that has acquired 3.3 GHz (3380-3400 MHz) and 3.5 GHz (3400-3460 MHz) continuous bandwidth spectrum was the fastest of these three at 212.77 Mbps. CSL and 3 Hong Kong were a close second and third, respectively. SmarTone, which launched its 5G network a month later, was fourth.

iPhone-12-5G-Median-Speeds_Amsterdam0121

The 3.5 GHz band is not yet available in the Netherlands, but this did not slow down Dutch operators in launching their commercial 5G networks in 2020. According to Speedtest Intelligence data, KPN Mobile was comfortably at the top, with a median download speed of 211.80 Mbps over 5G using the iPhone 12 in Amsterdam during Q4 2020. T-Mobile was second and Vodafone third.

iPhone-12-5G-Median-Speeds_Madrid_0121

While Spanish operators currently benefit from the n78 band, the next step is expected to be the delayed addition of low bands (700 MHz). In Madrid, Vodafone showed the fastest median download speed over 5G using the iPhone 12 during Q4 2020 at 232.51. Orange was second fastest, Yoigo third and Movistar at fourth.

You are welcome to give us feedback on your iPhone 12 experience, and we will continue to track the performance of Apple’s 5G devices

From speedtest

快过年了,用JS放个烟花吧

前端工程师的绽放时刻来了。

快过年了,现在全国大部分地区都禁止燃放烟花,而工程师们大部分也在cold的冬夜里不停的code,code,code…,想看个烟花简直难上加难。

但是,没有什么是能够难住工程师的,尤其是前端工程师,不就是用js放个烟花,安排。

如何实现用js放烟花?

第一步:先创建一个Canvas;

第二步:分析烟花的运动轨迹;

第三步:初步实现动效

第四步:优化,让烟花更逼真

第五步:兼容任意网页可绽放

js实现烟花绽放效果

具体的细节请参考 大帅搞前端 的微功号

代码我替大家扒下来了:https://codepen.io/jackrugile/pen/acAgx

希望对大家有用。

web前端号:持续挖掘有用的前端干货!

抢不到票?不存在的。一个前端工程师用node写了个抢票软件,还能自动提醒

临近春节,在外胆战心惊奋斗一年的我们终于要准备回家了。但再远的距离都敌不过一张火车票的距离。一年一度的春运即将上演,抢票大战正在激烈进行,今年你抢到票了吗?

对互联网从业人员来说,抢票具有天然的优势。不仅可以时时刻刻盯盘,而且主要互联网是工程师的地盘,有主场作战的优势,相当惬意。对工程师来说,抢不到票是不存在的,如果抢不到,那他就写一个程序。这就有这么一个前端狗,自己动手用node.js 写了一个辅助抢票程序,还能设置短信提醒,可以说是捡漏神器。

下面来看看这个前端工程师是如何用node js 写出这个软件的。主要的步骤有:

获取接口信息、Node.js 请求目标接口、开发通知功能。

具体的步骤有:

node js开发抢票和提醒功能

该软件引来众人围观

node js 开发抢票和短信提醒功能案例

受限于版权,更具体的开发教程请查看掘金网 西岚。

说明:仅用于学习研究,切勿大量使用

Web前端号: 持续挖掘有用的前端知识

大秦转债什么时候上市?多少钱卖出?

大秦转债2020年12月16日公布了中签结果,但却迟迟没有发布上市日期,网友很捉急,大秦转债什么时候上市?上市以后,多少钱卖出?大秦转债的最高点预计是多少?

这些问题我们一一来探讨:

大秦转债什么时候上市

公布了,大秦转债的上市日期是2021年1月15日,周五,大家记得加上提醒,尤其是上市首日准备卖出获利了结的小伙伴。网友们估计都等着急了,磨磨唧唧的终于上市了,是肉是汤总算能喝上了。

大秦转债多少钱卖出?

大秦转债的最新相关数据:

转股溢价率:17.67%

正股价:6.51

转股价:7.66

转股价值:94.99

债券年收益:2.26%,

大秦转债评级:AAA级

大秦转债相关数据

基本面信息:

12月14日,大秦铁路公开发行320亿元可转换公司债券,简称为“大秦转债”。大秦铁路主要运输晋、陕、蒙地区的煤炭。2019年晋陕蒙三省区原煤产量占全国的70.5%,是我国煤炭最主要的生产、外销地区。参考近似评级和转股价值的可转债溢价率,首日上市价格应该在110元附近,即每中一签盈利100元。

总体而言,大秦转债在110左右卖出是比较合适的,最高能到多少还要看具体的情况,市场情绪也同样不容忽略。

JS 数组方法都有哪些?如何使用?这里都整理好了,超详细

Js是前端的灵魂,也是难点。二数组是js的中使用最频繁的概念,理解好数组方法,熟练掌握数组方法的使用,对于前端开发来说非常重要。但是JS 数组方法都有哪些?如何使用呢?本文就数组方法做一个小专题,整理js数组的方法以及其使用方法,并通过代码实例来说明。

创建数组

首先是数组的创建

1.使用数组字面量表示法

var arr4 = [];   //创建一个空数组var arr5 = [20];   // 创建一个包含1项数据为20的数组var arr6 = ["lily","lucy","Tom"];   // 创建一个包含3个字符串的数组

2.使用 Array 构造函数

无参构造
var arr1 = new Array();   //创建一个空数组
带参构造

如果只传一个数值参数,则表示创建一个初始长度为指定数值的空数组

var arr2 = new Array(20);   // 创建一个包含20项的数组

如果传入一个非数值的参数或者参数个数大于 1,则表示创建一个包含指定元素的数组

var arr3 = new Array("lily","lucy","Tom");   // 创建一个包含3个字符串的数组var array4 = new Array('23'); // ["23"]

3.Array.of 方法创建数组(es6 新增)

ES6 为数组新增创建方法的目的之一,是帮助开发者在使用 Array 构造器时避开 js 语言的一个怪异点。

Array.of()方法总会创建一个包含所有传入参数的数组,而不管参数的数量与类型。

let arr = Array.of(1, 2);console.log(arr.length);//2let arr1 = Array.of(3);console.log(arr1.length);//1console.log(arr1[0]);//3let arr2 = Array.of('2');console.log(arr2.length);//1console.log(arr2[0]);//'2'

4.Array.from 方法创建数组(es6 新增)

在 js 中将非数组对象转换为真正的数组是非常麻烦的。在 ES6 中,将可迭代对象或者类数组对象作为第一个参数传入,Array.from()就能返回一个数组。

function arga(...args) {  //...args剩余参数数组,由传递给函数的实际参数提供    let arg = Array.from(args);    console.log(arg);}arga('arr1', 26, 'from'); // ['arr1',26,'from']
映射转换

如果你想实行进一步的数组转换,你可以向 Array.from()方法传递一个映射用的函数作为第二个参数。此函数会将数组对象的每一个值转换为目标形式,并将其存储在目标数组的对应位置上。

function arga(...args) {       return Array.from(args, value => value + 1);}let arr = arga('arr', 26, 'pop');console.log(arr);//['arr1',27,'pop1']

如果映射函数需要在对象上工作,你可以手动传递第三个参数给 Array.from()方法,从而指定映射函数内部的 this 值

const helper = {  diff: 1,  add(value) {    return value + this.diff;  }}function translate() { //arguments 是一个对应于传递给函数的参数的类数组对象  return Array.from(arguments, helper.add, helper); }let arr = translate('liu', 26, 'man');console.log(arr); // ["liu1", 27, "man1"]

数组方法

其次是数组的操作方法.

数组原型方法主要有以下这些

  • join():用指定的分隔符将数组每一项拼接为字符串
  • push() :向数组的末尾添加新元素
  • pop():删除数组的最后一项
  • shift():删除数组的第一项
  • unshift():向数组首位添加新元素
  • slice():按照条件查找出其中的部分元素
  • splice():对数组进行增删改
  • fill(): 方法能使用特定值填充数组中的一个或多个元素
  • filter():“过滤”功能
  • concat():用于连接两个或多个数组
  • indexOf():检测当前值在数组中第一次出现的位置索引
  • lastIndexOf():检测当前值在数组中最后一次出现的位置索引
  • every():判断数组中每一项都是否满足条件
  • some():判断数组中是否存在满足条件的项
  • includes():判断一个数组是否包含一个指定的值
  • sort():对数组的元素进行排序
  • reverse():对数组进行倒序
  • forEach():ES5 及以下循环遍历数组每一项
  • map():ES6 循环遍历数组每一项
  • copyWithin():用于从数组的指定位置拷贝元素到数组的另一个指定位置中
  • find():返回匹配的值
  • findIndex():返回匹配位置的索引
  • toLocaleString()、toString():将数组转换为字符串
  • flat()、flatMap():扁平化数组
  • entries() 、keys() 、values():遍历数组

下面分别对各个方法的功能和使用进行探讨

1.join()

join()方法用于把数组中的所有元素转换一个字符串。

元素是通过指定的分隔符进行分隔的。默认使用逗号作为分隔符

var arr = [1,2,3];console.log(arr.join());   // 1,2,3console.log(arr.join("-"));   // 1-2-3console.log(arr);   // [1, 2, 3](原数组不变)

通过join()方法可以实现重复字符串,只需传入字符串以及重复的次数,就能返回重复后的字符串,函数如下:

function repeatString(str, n) {//一个长度为n+1的空数组用string去拼接成字符串,就成了n个string的重复 return new Array(n + 1).join(str);}console.log(repeatString("abc", 3));   // abcabcabcconsole.log(repeatString("Hi", 5));   // HiHiHiHiHi
2.push()和 pop()

push() 方法从数组末尾向数组添加元素,可以添加一个或多个元素。

pop() 方法用于删除数组的最后一个元素并返回删除的元素。

var arr = ["Lily","lucy","Tom"];var count = arr.push("Jack","Sean");console.log(count);  // 5console.log(arr);   // ["Lily", "lucy", "Tom", "Jack", "Sean"]var item = arr.pop();console.log(item);   // Seanconsole.log(arr);   // ["Lily", "lucy", "Tom", "Jack"]
3.shift() 和 unshift()

shift() 方法用于把数组的第一个元素从其中删除,并返回第一个元素的值。

unshift() 方法可向数组的开头添加一个或更多元素,并返回新的长度。

var arr = ["Lily","lucy","Tom"];var count = arr.unshift("Jack","Sean");console.log(count);   // 5console.log(arr);   //["Jack", "Sean", "Lily", "lucy", "Tom"]var item = arr.shift();console.log(item);   // Jackconsole.log(arr);   // ["Sean", "Lily", "lucy", "Tom"]
4.sort()

sort() 方法用于对数组的元素进行排序。

排序顺序可以是字母或数字,并按升序或降序。

默认排序顺序为按字母升序。

var arr1 = ["a", "d", "c", "b"];console.log(arr1.sort());   // ["a", "b", "c", "d"]arr2 = [13, 24, 51, 3];console.log(arr2.sort());   // [13, 24, 3, 51]console.log(arr2);   // [13, 24, 3, 51](元数组被改变)

为了解决上述问题,sort()方法可以接收一个比较函数作为参数,以便我们指定哪个值位于哪个值的前面。

比较函数接收两个参数,如果第一个参数应该位于第二个之前则返回一个负数,如果两个参数相等则返回 0,如果第一个参数应该位于第二个之后则返回一个正数。以下就是一个简单的比较函数:

function compare(value1, value2) {    if (value1 < value2) {     return -1;    } else if (value1 > value2) {     return 1;    } else {     return 0;    }}arr2 = [13, 24, 51, 3];console.log(arr2.sort(compare));   // [3, 13, 24, 51]

如果需要通过比较函数产生降序排序的结果,只要交换比较函数返回的值即可:

function compare(value1, value2) {    if (value1 < value2) {     return 1;    } else if (value1 > value2) {     return -1;    } else {     return 0;    }}arr2 = [13, 24, 51, 3];console.log(arr2.sort(compare));   // [51, 24, 13, 3]
5.reverse()

reverse() 方法用于颠倒数组中元素的顺序。

var arr = [13, 24, 51, 3];console.log(arr.reverse());   //[3, 51, 24, 13]console.log(arr);   //[3, 51, 24, 13](原数组改变)
6.concat()

concat() 方法用于连接两个或多个数组。

该方法不会改变现有的数组,而仅仅会返回被连接数组的一个副本。

var arr = [1,3,5,7];var arrCopy = arr.concat(9,[11,13]);console.log(arrCopy);   //[1, 3, 5, 7, 9, 11, 13]console.log(arr);   // [1, 3, 5, 7](原数组未被修改)

从上面测试结果可以发现:传入的不是数组,则直接把参数添加到数组后面,如果传入的是数组,则将数组中的各个项添加到数组中。但是如果传入的是一个二维数组呢?

var arrCopy2 = arr.concat([9,[11,13]]);console.log(arrCopy2);   //[1, 3, 5, 7, 9, Array[2]]console.log(arrCopy2[5]);   //[11, 13]
7.slice()

slice():返回从原数组中指定开始下标到结束下标之间的项组成的新数组。

slice()方法可以接受一或两个参数,即要返回项的起始和结束位置。

只有一个参数的情况下, slice()方法返回从该参数指定位置开始到当前数组末尾的所有项。

如果有两个参数,该方法返回起始和结束位置之间的项,但不包括结束位置的项。

当出现负数时,将负数加上数组长度的值(6)来替换该位置的数

var arr = [1,3,5,7,9,11];var arrCopy = arr.slice(1);var arrCopy2 = arr.slice(1,4);var arrCopy3 = arr.slice(1,-2);//相当于arr.slice(1,4)var arrCopy4 = arr.slice(-4,-1);//相当于arr.slice(2,5)console.log(arr);   //[1, 3, 5, 7, 9, 11](原数组没变)console.log(arrCopy);   //[3, 5, 7, 9, 11]console.log(arrCopy2);   //[3, 5, 7]console.log(arrCopy3);   //[3, 5, 7]console.log(arrCopy4);   //[5, 7, 9]
8.splice()

splice():很强大的数组方法,它有很多种用法,可以实现删除、插入和替换

######## 1.删除元素,并返回删除的元素

可以删除任意数量的项,只需指定 2 个参数:要删除的第一项的位置和要删除的项数。例如, splice(0,2)会删除数组中的前两项。

var arr = [1,3,5,7,9,11];var arrRemoved = arr.splice(0,2);console.log(arr);   //[5, 7, 9, 11]console.log(arrRemoved);   //[1, 3]

######## 2.向指定索引处添加元素

可以向指定位置插入任意数量的项,只需提供 3 个参数:起始位置、 0(要删除的项数)和要插入的项。例如,splice(2,0,4,6)会从当前数组的位置 2 开始插入 4 和 6。

var array1 = [22, 3, 31, 12];array1.splice(1, 0, 12, 35);  //[]console.log(array1); // [22, 12, 35, 3, 31, 12]

######## 3.替换指定索引位置的元素

可以向指定位置插入任意数量的项,且同时删除任意数量的项,只需指定 3 个参数:起始位置、要删除的项数和要插入的任意数量的项。插入的项数不必与删除的项数相等。例如,splice (2,1,4,6)会删除当前数组位置 2 的项,然后再从位置 2 开始插入 4 和 6。

const array1 = [22, 3, 31, 12];array1.splice(1, 1, 8);   //[3]console.log(array1);  // [22, 8, 31, 12]
9.indexOf()和 lastIndexOf()

接收两个参数:要查找的项和(可选的)表示查找起点位置的索引。

indexOf():从数组的开头(位置 0)开始向后查找。

lastIndexOf:从数组的末尾开始向前查找。

这两个方法都返回要查找的项在数组中的位置,或者在没找到的情况下返回-1。在比较第一个参数与数组中的每一项时,会使用全等操作符

var arr = [1,3,5,7,7,5,3,1];console.log(arr.indexOf(5));   //2console.log(arr.lastIndexOf(5));   //5console.log(arr.indexOf(5,2));   //2console.log(arr.lastIndexOf(5,4));   //2console.log(arr.indexOf("5"));   //-1
10.forEach()

forEach():对数组进行遍历循环,对数组中的每一项运行给定函数。这个方法没有返回值。参数都是 function 类型,默认有传,。

参数分别为:遍历的数组内容;第对应的数组索引,数组本身

var arr = [11, 22, 33, 44, 55];arr.forEach(function(x, index, a){ console.log(x + '|' + index + '|' + (a === arr));});输出为: 11|0|true 22|1|true 33|2|true 44|3|true 55|4|true
11.map()

map() 方法返回一个新数组,数组中的元素为原始数组元素调用函数处理后的值。

map() 方法按照原始数组元素顺序依次处理元素。

该方法不会改变原数组

var arr = [1, 2, 3, 4, 5];var arr2 = arr.map(function(item){ return item*item;});console.log(arr2);  //[1, 4, 9, 16, 25]
12.filter()

filter():“过滤”功能,数组中的每一项运行给定函数,返回满足过滤条件组成的数组。

var arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];var arr2 = arr.filter(function(x, index) { return index % 3 === 0 || x >= 8;});console.log(arr2);  //[1, 4, 7, 8, 9, 10]
13.fill() es6 新增

fill()方法能使用特定值填充数组中的一个或多个元素。当只是用一个参数时,该方法会用该参数的值填充整个数组。

let arr = [1, 2, 3, 'cc', 5];arr.fill(1);console.log(arr);//[1,1,1,1,1];

如果不想改变数组中的所有元素,而只是想改变其中一部分,那么可以使用可选的起始位置参数与结束位置参数(不包括结束位置的那个元素)

3 个参数: 填充数值,起始位置参数,结束位置参数(不包括结束位置的那个元素)

let arr = [1, 2, 3, 'arr', 5];arr.fill(1, 2);console.log(arr);//[1,2,1,1,1]arr.fill(0, 1, 3);console.log(arr);//[1,0,0,1,1];
14.every()

every():判断数组中每一项都是否满足条件,只有所有项都满足条件,才会返回 true。

var arr = [1, 2, 3, 4, 5];var arr2 = arr.every(function(x) { return x < 10;});console.log(arr2);  //truevar arr3 = arr.every(function(x) { return x < 3;});console.log(arr3);  // false
15.some()

some():判断数组中是否存在满足条件的项,只要有一项满足条件,就会返回 true。

var arr = [1, 2, 3, 4, 5];var arr2 = arr.some(function(x) { return x < 3;});console.log(arr2);  //truevar arr3 = arr.some(function(x) { return x < 1;});console.log(arr3);  // false
16.includes() es7 新增

includes() 方法用来判断一个数组是否包含一个指定的值,如果是返回 true,否则 false。

参数有两个,其中第一个是(必填)需要查找的元素值,第二个是(可选)开始查找元素的位置

const array1 = [22, 3, 31, 12, 'arr'];const includes = array1.includes(31);console.log(includes); // trueconst includes1 = array1.includes(31, 3); // 从索引3开始查找31是否存在console.log(includes1); // false

需要注意的是:includes使用===运算符来进行值比较,仅有一个例外:NaN 被认为与自身相等

let values = [1, NaN, 2];console.log(values.indexOf(NaN));//-1console.log(values.includes(NaN));//true
17.reduce()和 reduceRight()

这两个方法都会实现迭代数组的所有项(即累加器),然后构建一个最终返回的值。

reduce()方法从数组的第一项开始,逐个遍历到最后。

reduceRight()则从数组的最后一项开始,向前遍历到第一项。

4 个参数:前一个值、当前值、项的索引和数组对象

var values = [1,2,3,4,5];var sum = values.reduceRight(function(prev, cur, index, array){return prev + cur;},10);   //数组一开始加了一个初始值10,可以不设默认0console.log(sum);  //25
18.toLocaleString() 和 toString()

将数组转换为字符串

const array1 = [22, 3, 31, 12];const str = array1.toLocaleString();const str1 = array1.toString();console.log(str); // 22,3,31,12console.log(str1); // 22,3,31,12
19. find()和 findIndex()

find()与 findIndex()方法均接受两个参数:一个回调函数,一个可选值用于指定回调函数内部的 this。

该回调函数可接受三个参数:数组的某个元素,该元素对应的索引位置,以及该数组本身。

该回调函数应当在给定的元素满足你定义的条件时返回 true,而 find()和 findIndex()方法均会在回调函数第一次返回 true 时停止查找

二者的区别是:find()方法返回匹配的值,而 findIndex()返回匹配位置的索引。

let arr = [1, 2, 3, 'arr', 5, 1, 9];console.log(arr.find((value, keys, arr) => {    return value > 2;})); // 3 返回匹配的值console.log(arr.findIndex((value, keys, arr) => {    return value > 2;})); // 2 返回匹配位置的索引
20.copyWithin() [es6 新增]

copyWithin() 方法用于从数组的指定位置拷贝元素到数组的另一个指定位置中。

该方法会改变现有数组

//将数组的前两个元素复制到数组的最后两个位置let arr = [1, 2, 3, 'arr', 5];arr.copyWithin(3, 0);console.log(arr);//[1,2,3,1,2]

默认情况下,copyWithin()方法总是会一直复制到数组末尾,不过你还可以提供一个可选参数来限制到底有多少元素会被覆盖。这第三个参数指定了复制停止的位置(不包含该位置本身)。

let arr = [1, 2, 3, 'arr', 5, 9, 17];//从索引3的位置开始粘贴//从索引0的位置开始复制//遇到索引3时停止复制arr.copyWithin(3, 0, 3);console.log(arr);//[1,2,3,1,2,3,17]
21.flat() 和 flatMap() es6 新增

flat() 方法会按照一个可指定的深度递归遍历数组,并将所有元素与遍历到的子数组中的元素合并为一个新数组返回。

该方法返回一个新数组,对原数据没有影响。

参数: 指定要提取嵌套数组的结构深度,默认值为 1。

const arr1 = [0, 1, 2, [3, 4]];console.log(arr1.flat());// expected output: [0, 1, 2, 3, 4]const arr2 = [0, 1, 2, [[[3, 4]]]];console.log(arr2.flat(2));// expected output: [0, 1, 2, [3, 4]]//使用 Infinity,可展开任意深度的嵌套数组var arr4 = [1, 2, [3, 4, [5, 6, [7, 8, [9, 10]]]]];arr4.flat(Infinity);// [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]// 扁平化数组空项,如果原数组有空位,flat()方法会跳过空位var arr4 = [1, 2, , 4, 5];arr4.flat();// [1, 2, 4, 5]

flatMap()方法对原数组的每个成员执行一个函数,相当于执行Array.prototype.map(),然后对返回值组成的数组执行flat()方法

该方法返回一个新数组,不改变原数组。

// 相当于 [[2, 4], [3, 6], [4, 8]].flat()[2, 3, 4].flatMap((x) => [x, x * 2])// [2, 4, 3, 6, 4, 8]
22. entries(),keys() 和 values() 【ES6】

entries(),keys()和values() —— 用于遍历数组。它们都返回一个遍历器对象,可以用for…of循环进行遍历

区别是keys()是对键名的遍历values()是对键值的遍历entries()是对键值对的遍历

for (let index of ['a', 'b'].keys()) {  console.log(index);  }  // 0  // 1  for (let elem of ['a', 'b'].values()) {  console.log(elem);  }  // 'a'  // 'b'  for (let [index, elem] of ['a', 'b'].entries()) {  console.log(index, elem);  }  // 0 "a"  // 1 "b" 

如果不使用for…of循环,可以手动调用遍历器对象的next方法,进行遍历。

let letter = ['a', 'b', 'c'];  let entries = letter.entries();  console.log(entries.next().value); // [0, 'a']  console.log(entries.next().value); // [1, 'b']  console.log(entries.next().value); // [2, 'c'] 

好了,以上就是整理的数组方法详解和代码实例,希望对大家有所帮助。记得把实例代码都敲一遍鸭。

展望2021年Web前端开发的七大趋势

前端开发技术不断更新和丰富,能做的事情也是越来越多,2021年web前端开发将继续飞速发展。新年伊始,我们来展望一下2021年web前端开发的七大趋势,希望对大家的学习和职场有助帮助。

网站不仅仅是代码的组合,传播上来说,你的网站是用户关于你的第一印象,在与其互动的过程形成的印象,对企业品牌都有着潜移默化的影响。现在的网站开发工作不只是代码搬运工,而是变得越来越具有创造性。同时市场上的新趋势不断影响着 Web 开发流程,为开发人员设计和构建网站带来了更多灵活和实用的方式。

2021年web前端开发的7大趋势
2021年web前端开发的7大趋势

渐进式 Web 应用开发(PWA)

PWA 看起来很像原生移动应用程序,但它实际上是一种网站。根据研究,PWA 的转换率比原生应用高 36%;因此,我们可以看到它的发展势头日趋明显。PWA 的主要目标是为使用各种类型设备的用户都带来类似移动应用的体验。

它们更具互动性和响应能力。PWA 正在变革用户体验,因为它的功能类似原生应用,却无需用户下载。一些业内知名企业,例如 Amazon、Twitter 和 Forbes,正在将原生和 Web 应用程序结合起来以增加转化率并降低流失率。由于 PWA 的脱机工作机制、快速加载和页面速度,越来越多的全球化企业正在使用它来加强品牌影响力。

由于 PWA 的可访问性和可靠性优势,这种应用的用户规模在持续增长,成为 2021 年的重要趋势。

深色主题 UI

我们已经在移动应用程序中看到了这种趋势,现在网站也正在朝着这一方向发展。夜晚或黑暗主题的用户界面对眼睛来说更安全、浏览起来更轻松。它不仅减少了过度的眼疲劳现象,而且还增强了对比度,使用户更容易看到浅色内容。这种主题还延长了设备续航时间,因为在 OLED 屏幕上,更多的黑色像素会消耗更少的电力。此外,它还为整个网站带来了相当时尚的风格,并提供最佳的用户体验。

这是 2021 年 Web 开发领域的流行趋势之一。行业头部品牌,如 WhatsApp、Facebook、Twitter、Android、Apple、YouTube、Reddit 等,都已经投身于这一潮流之中。

人工智能驱动的聊天机器人

在 2021 年,对基于 AI 的沟通交流需求将不断增长。网站将投入更多资源来构建基于 AI 技术的聊天机器人和虚拟助手,以改善客户体验。

聊天机器人可能收获的风评不是很好,但它们确实很方便。用户访问网页时,页面上的聊天机器人可以立即与他们建立联系。它们为用户提供了快速的响应,这可以帮助企业避免服务延误,降低客户流失率。

聊天机器人可以从同用户的交流中收集数据,并基于这些数据进行训练和改进,进而提供更好的解决方案。此外,它们使用自然语言编程技术来与人类更加自然地互动。

语音识别技术和认知智能相结合,使聊天机器人可以做到比人工支持人员更高的可靠性。在全球范围内,电子商务、旅行和旅游业、医疗保健等行业正在快速意识到聊天机器人的重要性。

单页网站

这种趋势在 2020 年已经非常明显了,在 2021 年也将一直持续下去。

构建复杂而全面的 Web 结构的时代已经一去不复返了。随着人们普遍习惯通过移动设备接入互联网,单页网站凭借更易浏览的优势大行其道,为不同主题构建单独页面的旧方法已然过时。

单页网站极大地减少了页面加载需求,并加快了页面响应速度,从而降低了流失率。由于其简单性,它在移动设备和台式机上均有很好的表现。而且,它的开发和托管工作并不昂贵。单页网站可以帮助企业用有限的内容吸引特定的目标受众。此外,它的简约设计更易阅读、更具吸引力。

语音识别技术

物联网(IoT)走上前台已经有一段时间了。在 2021 年,我们可以看到或期望在一个重要领域看到显著的进步,那就是语音识别。根据研究,到 2023 年预计将有 80 亿个语音助手投入使用。

语音搜索功能的应用将极大地影响开发人员的工作方式。基于语音的电子商务有望主导市场。像 Google、Amazon、Microsoft 等公司都在使用这项技术来开发创新产品和服务。

此外,随着智能扬声器和助手的问世,语音识别技术已经达到了一个全新的发展水平。因此,开发人员需要充分优化网站来增强语音搜索功能。

云计算 

根据 Gartner 的数据,到 2021 年,公共云服务市场预计将增长到 3069 亿美元。云计算在 2021 年的前景是可以预见的。

云计算可预防数据丢失和数据过载。因此它具有替换常规服务器的能力。这种趋势将在未来几年内改变 Web 开发的方式,因为它不仅可以降低开发成本,而且可以增强整个 Web 架构。Google Cloud Functions、Azure Functions、AWS Lambda 等服务都是流行的云计算示例。

考虑到当前的全球形势,许多企业都依赖远程解决方案。这些 Web 开发趋势可以帮助企业构建无缝的工具。Angular.Js、Node.Js 等框架将在 2021 年继续得到高度关注,直到有更好的技术取代它们。AR/VR、物联网、motion UI、高性能移动页面和区块链技术的进化也将持续。

网站安全性

安全,是一个在任何时候都不能忽略的问题。根据研究,每天有将近 50,000 个网站被黑客攻破。这是一个令人担忧的数字,因为有太多的公司正在使用数字平台来运营自己的业务。另一方面,网站上还经常包含许多敏感的客户信息。2021 年,很多严格的网站安全协议将开始普及,提升网站的合规水平。

改用 HTTPS 协议将是所有网站开发人员和所有者的首要任务。HTTPS 协议是所有网站的基础安全标准,它可以确保通信的安全性,不会受到第三方的任何威胁。Google 已将不受 HTTPS 保护的网站标记为不安全。

定期更新软件对于确保网站安全性而言至关重要。行业还将普遍采用有效的密码管理解决方案。

据统计,全球已有超过 17亿个网站。这意味着,几乎在每一个细分领域都有无数网站在进行着激烈的竞争。开发人员应该了解和发现更多创新的 Web 开发方式,并通过这些方法可以提升企业网站在搜索引擎上的排名,增加企业的曝光和流量,促进企业业务的发展。毕竟帮老板挣到钱,工程师才有福利鸭。

2021年加油

前端学着学着就迷茫了,越来越吃力?大神前端学习方法带你突破

前端不仅知识广,而且近几年又向纵深发展,难度也随之上升。总结起来就是前端越来越有用了,也越来越难了。不少想学习前端的小伙伴在学习了一段时间后,感觉前端越学越迷茫,越学越吃力,有很大的挫败感,这很可能是前端学习方法出了问题,这里总结一位一线前端大神(职场项目实践大神)的学习经验,希望对大家学习有所启发。

大神简介:工作两年多,已熟练掌握大部分前端原理、框架。工作上已经几乎没有解决不了的问题(除了那种跟着手机壳变换颜色的奇葩需求),成功超越老员工,被安排去面试(虐待)新人。

一、基础三大件要扎实

HTML、CSS、JavaScript 老三样必须完全掌握。不懂得建议直接查 MDN。

HTML重点掌握语义化。区分块级和内联标签。还有就是定义 head 里面一些meta 了解下。其他用到查文档,然后在实践中用熟悉就好了。

CSS。重点看盒子模型,定位,层级,过渡,动画和 transform。知道原理和规则。大部分工作都是照着设计稿化。掌握上面几个99%还原也不难。接下来重点学习几种常见的布局。完了之后去搞flex。最后搞下sass、less。基本就差不多了。

JavaScript。JS是重点和难点,红宝书看一遍掌握基础,进阶去看《你不知道的 JavaScript》。就这两套足够了,别搞那么多。争取每个知识点搞懂,后续ES6也就基本没啥问题了。下面几个问题必须拿下,优先级如下:

  1. this 用法,相关原理
  2. 原型/原型链
  3. 闭包
  4. 面向对象相关
  5. 同步异步/回调/promise/async、await
  6. 模块化 CommonJS, AMD

先搞这懂这些比较难的概念,对你JS理解更加深入。接下来在开始看框架方面

二、框架

前期要会用,后期要懂原理。

新人先搞 Vue。Vue 算是比较简单的框架了,上手容易。照着官方文档来问题不大。原理方面要提高自己认识。学习怎么看源码。github常去逛逛。

学习框架之前,我其实特别建议,新人先去了解 Babel 和 webpack 不仅仅是使用。一些原理方面的东西工作中也会用到。babel 里面会有教你如何编译代码。webpack教你如和打包文件。自己手写编译器和打包工具也不是特别难。反正对之后看vue、react源码帮助挺大。

搞完 Vue 全家桶,去了解下 React,React hooks 学习下新的理念。再回过头来看Vue。你会发现他们是如此的相似去又不同。

多去实践总结,对整体框架理解会越来越深刻。

今天先马到这里。想写的太多,马上就要上班下次有空再来码…

三、学会看源码

新人刚开始看源码,会陷入两个困境中。一是无从下手。二是看了之后感觉没啥收获。

这个也很正常。一般我们熟知的框架都有个几千甚至上万个PR。太大细节会干扰你。掌握整个节奏和流程。学习原理也比较吃力。就连找个入口都像大海捞针一样。建议从下面几个方面入手:

  1. 挑简单的上手。别一开始就搞 vue、react、webpack。太难,会直接劝退新人。不要为了面试而去读。反而效果不好,面试稍微问深入一点就答不出来了。平时有兴趣多琢磨琢磨。按照难易程度,函数库 < 组件库 < 框架 < 工程化 分别典型代表 lodash < vant < vue < webpack
  2. 手撸简易模型。像vue, webpack, babel 都有简易项目给你撸。有的创始人(尤哥)还直播手撸。国外的更多,youtube 一搜一大堆。就算不看源码,照着写出了简易 demo 对原理和理解提升都是很大的。
  3. 调试开源项目。先把项目拉下来。在vscode里面跑下,核心函数多打几个断点。看看里面变量是怎么diff的。对理解更深刻了。

看了源码是别人的,学到了是自己的。学习时候边记笔记,边思考原理,总结经验。下面来谈谈前端工程化怎么弄。

四、前端工程化

现在最流行的打包工具 webpack 用起来。当然直接用 vue-cli2、vue-cli3、create-react 都是可以的。但是 webpack 相关还是得掌握。

首先重点搞下babel、webpack。学习下编译,打包的原理。自己配置下 webpack。尝试自己去写下下 webpack 的 loader 和 plugin。学习这些之前要懂一点 node.js, node.js 不需要全部学习。一般就日常用到读写文件fs接口,path 路径接口。这些 api 都不难写几个 demo 就懂了。基本上webpack 里面配置文件也没用到多少 node 的东西。最后自己学会配置webpack的配置文件。

如果想深想去优化打包体积和速度,就需要去了解很多webpack插件。webpack 里面最核心的就是插件了。

当然前端工程化不仅仅是这些,CI/CD可持续集成, Umi 了解下。shell各种脚本自动化命令、代码生成技术了解下。

五、性能优化

一般来说。性能优化没什么系统化的文档供人学习。完全靠一些经验和自己的实践。

我们常提到性能好坏是由什么来衡量呢?

访问页面地址 –> 页面首次加载数据 –> 渲染出完整页面的时长

非首次情况下,命中缓存的加载缓存数据 –> 渲染出完整页面的时长。

一般我从下面几个方面着手去做,一般问题都不大。

减小资源(静态资源,后端加载的数据)大小

  • 压缩代码HTML/CSS/JS
  • 压缩图片、音视频大小
  • Tree-Sharking 消除无用代码

以上webpack都可以搞定

避免同一时间的过多次数请求

  • CSS 实现雪碧图:使用background-position共享一张图
  • 图片懒加载:监听滚动后offsetTop,  使用src 替换 src(真实路径)
  • 列表懒加载(分批加载):监听滚动后offsetTop, 发送请求加载下一页的数据
  • 路由懒加载
  • 代码分包分块加载(webpack)
  • 预加载技术
  • 小程序分包、预下载等。

利用缓存(空间换时间)

  • CDN 内容分发:获取更近网络节点缓存下来的静态资源
  • 浏览器缓存(自带)
  • 部分资源保存在LocalStorage或者APP缓存中(手动操作)

其他

  • SSR 服务端渲染:解决SPA框架带来JS动态渲染页面带来的延迟和白屏问题。

这些都可以去实践的,难度不大。难度大的地方可能是 dom 节点成千上万的时候渲染的性能问题。这个场景遇到的很少,方案很多。不同人有不同解决方案,有功夫可以自己去尝试尝试。

上面提到很多点都可以深入到很深。由于篇幅原因,点到即止。

纯粹是把一些我以前走过的弯路掰直了再分享给大家。毕竟不是《前端入门到精通》哈哈哈

六、移动端web开发

前端现在为什么这么火?各个公司都还挺缺优秀的前端。原因在于技术红利

移动端web流行起来之后,特别是H5和小程序,带动了多少前端就业,前端迅速取代了安卓和iOS 的大量岗位。

回到正题:所以作为前端人,移动web一般是都要接触的。不同于PC 端。

移动端有哪些东西呢? 不需要全部懂,差不多知道就行了。要用的时候再去学。

  1. 绝对单位换相对单位:px => rem / vw / rpx
  2. 弹性布局:使用flex、grid布局
  3. hairline (1px的粗线处理):使用伪元素 + transform: scale(倍数) 缩放线框
  4. WebView 环境了解下
  5. 安卓iOS 兼容踩坑:点击延迟、穿透、滚动不流畅、安全区域等等。
  6. 小程序开发相关踩坑
  7. JSBridge: H5 与App 通信
  8. H5动画制作
  9. 跨平台框架:react native、weex、flutter 等等

简单的说移动web 就是:html/css/js 跑在手机app 里面的WebView(web运行环境)。

小程序/公众号就是在这个基础上,将自己APP里面的WebView 租售给其他人使用。

微信APP —– 提供SDK —-> 微信webview —– 提供运行环境—–> 公众号h5 / 小程序

为什么微信可以容纳几乎无限的H5/小程序页面呢?

因为公众号/小程序的代码都存储在云端,通过不同的路由就可以给几乎无数的开发者使用。

使得微信成为一个运行环境+入口的存在。

七、做前端越学越觉得吃力?

前端入门比较简单,刚做时前端不吃力。因为我是软件工程专业,学前端之前,学过 C/C++、Java、PHP、.net 成绩还不错基本都是90多分。感觉自己干后端也不吃力。实验室里面的项目都是前后都写。最爱 PHP,当时最崇拜鸟哥。本以为以后就走上PHP后端工程师的道路了,成为鸟哥那样的大神。

由于项目需要的原因,后来渐渐开始学起学 HTML、CSS、JavaScript 这些语法相关的东西。刚接触时没有感觉太大难度。

当时就想着怎么把页面搞好看,搞各种动画炫技。写一个小球从下面弹出来的效果,换各种姿势弹出。当时觉得前端真的有意思,就入了前端的坑。入坑前,以为前端就是搞各种漂亮的页面,各种特性惊艳别人。

随着接触的越来越深。接触到了 AJAX, jQuery ,Bootstrap,前端开始注重体验。各种框架横空出世 backbone => Angular => React => Vue 眼花缭乱。

折腾了 JQuery 开始折腾 backbone 觉得前端还能这样玩。有些迷茫了,感觉脑袋快要炸了,那段时间特别焦虑,疯狂看书写代码,怎么这么多东西要学啊。

JavaScript 也不精通,到原型就不理解了,虽然有C++,JAVA面向对象的知识,但JavaScript 你怎么和别人玩的不是一个套路啊。当时就都用ES6了, 行,学。都用Sass了,行,学。不学也可以,看不懂别人的代码呀。

毕业前为准备校招前端工程师,真的很吃力。就怕校招面试时,自己啥都不懂。

功夫不负有心人,校招时候顺利拿到了自己满意的Offer。记得当时和面试官对答入流,好像找到知音一样。面试官也是过来人,基本能问的都问了。

拿到Offer之后就去了实习。实习第一个任务:将一个ES6的后台管理系统重构成 Vue2.0 全家桶的项目。有个导师带,但是她和我是不同项目,出了架构以外代码都是自己写。

这个阶段还是收获了很多:

  1. git 命令特别熟练。commit、stash、merge/rebase、cherry-pick、push/pull/fetch、reset等等基本都敲都特别多了
  2. 严格了代码规范。Eslint、prettier 都用起来了
  3. 会自己写业务组件,会封装高级组件、写常规页面了。基本上大部分不是特别复杂的交互都ok。难一点多找下资料可以做出来。
  4. 学会管理API了。自己尝试封装了 axios。统一处理错误和弹窗。
  5. 会抽取公共css、JavaScript 函数,编写CSS 变量和JavaScript 常量了
  6. webpack 能看懂配置文件了。

实习过后顺利转正。转正之后,换了另外一个导师带,加入到项目组作为一个比较大的项目的核心开发。基本不再做管理系统了。主要做一个saas 平台。涉及比较难的富文本编辑,UI 拖拽生产文章,数据可视化生产报表等等。还写了几个谷歌浏览器插件。

  1. 开始提升写页面效率,写的比较快了。
  2. 研究 webpack 的插件打包编译效率
  3. 研究 babel 编译原理
  4. 研究了 Vue 编译的一些原理
  5. 研究了 一些图表的使用,多半使用的echart。常规图表基本都用过。
  6. CI & CD 自己去搭建。学了一些 shell 脚本开发。研究了 docker 相关的东西。
  7. 尝试去写基础组件,搭建基础组件库。
  8. 学习 React 相关的语法。
  9. 研究富文本编辑,图片压缩裁剪原理等等
  10. 写一个简单的微信公众号,接触到了 H5 开发。

工作第一年,基本上主战场在PC 端。前半年挺吃力,后半年熟练后比较从容。会怼产品,喷设计,会和后端兄弟配合默契。和团队感情也很深了。

无奈项目由于某些原因终止,团队解散,调到新团队。在老东家工作一年多后,由于个人原因离开去了一家新的的公司,主战场从PC 到了手机。开始接触移动H5、hybrid 开发。

八、学习吃力的原因肯定是学习方法有问题。总结下一般怎么才能真正学到东西

  1. 详略得当:前端知识太多,抓重点学,不要像背字典一样。
  2. 不要急着写代码,先理清流程(以一个函数为单位,可以先写注释)再写代码。
  3. 看视频看讲解是会误以为自己会了,其实并没有。
  4. 学会总结:一句话可以讲清楚的事情,不要多说一句。减少心智负担。
  5. 不介意复制代码,但是要知道这个代码里面大致实现原理。感兴趣自己重写一个。
  6. 较大的项目,不要急着看代码。可以先把项目跑起来。通过改代码里面的参数来理解里面的核心流程。
  7. demo 式编程。对于新框架,参考demo来上手更快更容易理解。
  8. 渐进式编程。对于比较复杂的功能/需求。不要想着一气呵成。先实现一个核心,每次往上面加细节,有点像绘画。
  9. 断点单步调试很有用,定位bug会更快。当然有些不易调试的应用选择打log。一次打 log 要多打点,免得打完log,有得再加。
  10. 黑盒太多的项目,实在找不到bug原因。发给同事帮忙看。可能很快就能看出来。当局者迷,旁观者清。(很多时候是拼写的问题)

以上是这位前端大神带来的分享,希望他的前端学习方法和学习路径有助于还在前端爬坡的前端工程师们。

如果觉得有用,也请大家分享给更多志同道合的同学,一起加油!